您的位置:首页 > 其它

[BZOJ4574][UOJ#196][Zjoi2016][区间DP][概率]线段树

2017-03-29 18:04 465 查看
ZJOI2016 DAY2 看不懂题解系列……

http://www.cnblogs.com/Dragon-Light/p/6475923.html

#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 410
#define P 1000000007

using namespace std;

typedef long long ll;

int n,m;
int A
,B
,R
;
ll cnt

,sum

;
ll f[2]

;

inline void rea(int &x){
char c=getchar(); x=0;
for(;c>'9'||c<'0';c=getchar());
for(;c>='0'&&c<='9';x=x*10+c-'0',c=getchar());
}

inline bool cmp(const int &a,const int &b){
return A[a]<A[b];
}

inline void solve(int l,int r,int x){
for(int i=l;i<=r;i++)
for(int j=l;j<=r;j++)
f[0][i][j]=f[1][i][j]=0;
f[0][l][r]=1;
for(int k=1;k<=m;k++){
for(int i=l;i<=r;i++){
ll w=0;
for(int j=r;j>=i;j--)
f[k&1][i][j]=w,w+=f[(k&1)^1][i][j]*(n-j);
}

for(ll j=l;j<=r;j++){
ll w=0;
for(int i=l;i<=j;i++)
f[k&1][i][j]=(f[k&1][i][j]+w)%P,w+=f[(k&1)^1][i][j]*(i-1);
}

for(int i=l;i<=r;i++)
for(int j=i;j<=r;j++)
f[k&1][i][j]=(f[k&1][i][j]+f[(k&1)^1][i][j]*cnt[i][j])%P;
}
for(ll i=l;i<=r;i++){
ll w=0;
for(int j=r;j>=i;j--){
w+=f[m&1][i][j];
sum[j][R[x]]=(sum[j][R[x]]+w)%P;
}
}
}

inline int calc(int x){
return x*(x+1)>>1;
}

int main(){
rea(n); rea(m);
for(int i=1;i<=n;i++) rea(A[i]),B[i]=i;
sort(B+1,B+1+n,cmp);
for(int i=1;i<=n;i++) R[B[i]]=i;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++) cnt[i][j]=calc(i-1)+calc(n-j)+calc(j-i+1);
for(int i=1;i<=n;i++){
int l=i,r=i;
while(l&&A[i]>=A[l]) l--;
while(r<=n&&A[i]>=A[r]) r++;
solve(l+1,r-1,i);
}
for(int i=1;i<=n;i++){
ll Ans=0;
for(int j=1;j<=n;j++){
//printf("%lld ",sum[i][j]);
if(sum[i][j]==0) continue;
for(int k=1;k<j;k++) sum[i][j]=(sum[i][j]+P-sum[i][k])%P;
Ans=(Ans+1ll*A[B[j]]*sum[i][j])%P;
}
printf("%lld%c",Ans,i==n?'\n':' ');
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: