bzoj 4574: [Zjoi2016] Segment tree

Description

Little Yuuka encountered a problem: there is a sequence a_1, a_2,?, a_n, q operations, each time change the number in an interval to the maximum value in the interval, ask what
is the last number. Little Yuuka quickly solved this problem using a segment tree. So the wise little Yuuka thought, if the operation is random , that is, in the q operations, an interval l, r
is randomly selected with equal probability each time , and then the number in this interval is changed to the maximum value (note this The interval of (n(n+1))/2), what is the expected size of each number at the end? Little Yuuka loves randomness very much, so the input sequence she gives is also random (see Data Scale and Conventions for random methods). For each number, output its expected value multiplied by ((n(n+1))/2)^q modulo 10^9+7.

Solution

Consider the value that each position will eventually become, this is not easy to calculate.
Consider each position as the range that the maximum value can affect.
Enumerate each point as the maximum value \(x\) , \(DP\) calculate the contribution
Let \ (f[k][i][j]\) represents the first \(k\) operations, the maximum value of \([i,j]\) is less than or equal to the number of solutions \(x\)
\(i-1 \) , \(j+1\) is larger than the maximum value of the interval, each time the selected interval contains these two positions, the interval will be shortened, otherwise the interval length will be
shortened and unchanged.
The number of solutions that is less than or equal to \(x\) is the number of solutions that are obtained, and the number of solutions equal to \(x\) is obtained
. Under random data, the complexity is expected \(O(q*n^2)\)

#include<bits/stdc++.h>
#define RG register
using namespace std;
const int N=405,mod=1e9+7;
int n,m,a[N],g[N],b[N],f[2][N][N],s[N][N];
inline void add(int &x,int y){x+=y;if(x>=mod)x-=mod;}
inline void solve(int l,int r,int p){
    for(int i=l;i<=r;i++)
        for(int j=l;j<=r;j++)f[0][i][j]=f[1][i][j]=0;
    bool t=0;
    f[0][l][r]=1;
    for(int P=1;P<=m;P++,t^=1){
        for(int i=l;i<=r;i++){
            int sum=0;
            for(RG int j=r;j>=i;j--){
                int w=f[t][i][j];
                add(f[t^1][i][j],sum);
                sum=(sum+1ll*w*(n-j))%mod;
            }
        }
        for(int j=l;j<=r;j++){
            int sum=0;
            for(RG int i=l;i<=j;i++){
                int w=f[t][i][j];f[t][i][j]=0;
                add(f[t^1][i][j],sum);
                add(f[t^1][i][j],1ll*w*(1ll*g[i-1]+g[j-i+1]+g[n-j])%mod);
                sum=(sum+1ll*w*(i-1))%mod;
            }
        }
    }
    for(int i=l;i<=r;i++)
        for(int j=i;j<=r;j++)
            if(f[t][i][j])
                for(RG int k=i;k<=j;k++)s[k][a[p]]=(s[k][a[p]]+f[t][i][j])%mod;
}
int main(){
    freopen("pp.in","r",stdin);
    freopen("pp.out","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),g[i]=i*(i+1)>>1,b[i]=a[i];
    sort(b+1,b+n+1);
    int tp=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+tp+1,a[i])-b;
    for(int i=1;i<=n;i++){
        int l=i,r=i;
        while(l>1 && a[l-1]<=a[i])l--;
        while(r<n && a[r+1]<=a[i])r++;
        solve(l,r,i);
    }
    for(int i=1;i<=n;i++){
        int ans=0;
        for(int j=1;j<=tp;j++)
            if(s[i][j]){
                for(int k=1;k<j;k++)s[i][j]=(s[i][j]-s[i][k]+mod)%mod;
                ans=(ans+1ll*b[j]*s[i][j])%mod;
            }
        printf("%d ",ans);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325272561&siteId=291194637