这题的前缀和开始没有想到。
如果不用前缀和状态是五维的。。。
由于数据随机所以不会有两个相等的数。
最终答案是求每个数在所有方案下的取值的和。
对于每个数dp一下,设当前数为val,区间[L,R]为以当前数为最大值的最大区间。
设
f[i][l][r]
表示前i个询问,区间[L,R]剩余的小于等于当前数的区间为[l,r]的方案数。
然后转移时处理一个前缀和可以O(1)转移。
对于[L,R]内的每一个点x,把
(val,∑l≤x,r≥xf[q][l][r])
加入x(表示x最终取值小于等于当前数的方案数为
∑l≤x,r≥xf[q][l][r]
)然后最后通过前缀和相减得到每个数最终每个取值的次数。
由于数据随机所以每个数的区间[L,R]的期望长度是O(logn)的。
不过最大的数区间长度一定为n,因此总复杂度
O(n2q)
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long
#define N 410
int n,q;
int a[N],f[2][N][N],sum1[2][N][N],sum2[2][N][N];
int cnt[N],tmp[N],ans[N];
vector<pair<int,int> >vec[N];
void clear(int x,int l,int r)
{
for(int i=l;i<=r;i++)
for(int j=i;j<=r;j++)
f[x][i][j]=sum1[x][i][j]=sum2[x][i][j]=0;
}
void getsum(int x,int l,int r)
{
for(int i=l;i<=r;i++)
for(int j=l;j<=i;j++)
sum1[x][j][i]=(sum1[x][j-1][i]+(ll)f[x][j][i]*(j-1))%mod;
for(int i=l;i<=r;i++)
for(int j=r;j>=i;j--)
sum2[x][i][j]=(sum2[x][i][j+1]+(ll)f[x][i][j]*(n-j))%mod;
}
void cal(int v,int x,int l,int r)
{
for(int i=l;i<=r;i++)tmp[i]=0;
for(int i=l;i<=r;i++)
for(int j=r;j>=i;j--)
f[x][i][j]=(f[x][i][j]+f[x][i][j+1])%mod;
for(int i=l;i<=r;i++)
for(int j=l;j<=i;j++)
tmp[i]=(tmp[i]+f[x][j][i])%mod;
for(int i=l;i<=r;i++)
vec[i].push_back(make_pair(v,tmp[i]));
}
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)cnt[i]=(ll)i*(i+1)/2%mod;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int now=1;now<=n;now++)
{
int L=now-1,R=now+1;
for(;L>0&&a[L]<a[now];L--);L++;
for(;R<=n&&a[R]<a[now];R++);R--;
f[0][L][R]=1;getsum(0,L,R);
for(int i=1;i<=q;i++)
{
for(int j=L;j<=R;j++)
for(int k=j;k<=R;k++)
f[i&1][j][k]=((ll)f[~i&1][j][k]*((cnt[j-1]+cnt[k-j+1])%mod+cnt[n-k])
+sum1[~i&1][j-1][k]+sum2[~i&1][j][k+1])%mod;
getsum(i&1,L,R);
}
cal(a[now],q&1,L,R);
clear(0,L,R);clear(1,L,R);
}
for(int i=1;i<=n;i++)
{
sort(vec[i].begin(),vec[i].end());
ans[i]=(ans[i]+(ll)vec[i][0].second*vec[i][0].first%mod)%mod;
for(int j=1;j<vec[i].size();j++)
ans[i]=(ans[i]+(ll)(vec[i][j].second-vec[i][j-1].second+mod)*vec[i][j].first)%mod;
printf("%d%c",ans[i],i==n ? '\n':' ');
}
return 0;
}