• bzoj4574 [Zjoi2016]线段树


    Description

    小Yuuka遇到了一个题目:有一个序列a_1,a_2,?,a_n,q次操作,每次把一个区间内的数改成区间内的最大值,问最后每个数是多少。小Yuuka很快地就使用了线段树解决了这个问题。于是充满智慧的小Yuuka想,如果操作是随机的,即在这q次操作中每次等概率随机地选择一个区间[l,r](1≤l≤r≤n),然后将这个区间内的数改成区间内最大值(注意这样的区间共有(n(n+1))/2个),最后每个数的期望大小是多少呢?小Yuuka非常热爱随机,所以她给出的输入序列也是随机的(随机方式见数据规模和约定)。对于每个数,输出它的期望乘((n(n+1))/2)^q再对10^9+7取模的值。

    Input

    第一行包含2个正整数n,q,表示序列里数的个数和操作的个数。接下来1行,包含n个非负整数a1,a2...an。N<=400,Q<=400

    Output

    输出共1行,包含n个整数,表示每个数的答案

    Sample Input

    5 5
    1 5 2 3 4

    Sample Output

    3152671 3796875 3692207 3623487 3515626

    正解:$dp$。

    这道题还是太鬼了,我直接给一个博客吧:题解

    根本就不想写题解了。。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define rhl (1000000007)
    14 #define N (410)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 
    19 using namespace std;
    20 
    21 int cal[N][N],a[N],s[N],rk[N],cnt[N],n,q;
    22 ll f[2][N][N],sum[N][N],ans;
    23 
    24 il int gi(){
    25   RG int x=0,q=1; RG char ch=getchar();
    26   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    27   if (ch=='-') q=-1,ch=getchar();
    28   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    29   return q*x;
    30 }
    31 
    32 il int cmp(const int &x,const int &y){ return a[x]<a[y]; }
    33 
    34 il void solve(RG int l,RG int r,RG int now){
    35   for (RG int i=l;i<=r;++i)
    36     for (RG int j=l;j<=r;++j) f[0][i][j]=f[1][i][j]=0;
    37   f[0][l][r]=1; RG ll res;
    38   for (RG int k=1,cur=1,p=0;k<=q;++k,p=cur,cur^=1){
    39     for (RG int j=l;j<=r;++j){
    40       res=0;
    41       for (RG int i=l;i<=j;++i)
    42     f[cur][i][j]=res,res+=f[p][i][j]*(ll)(i-1);
    43     }
    44     for (RG int i=l;i<=r;++i){
    45       res=0;
    46       for (RG int j=r;j>=i;--j){
    47     (f[cur][i][j]+=res+f[p][i][j]*(ll)cal[i][j])%=rhl;
    48     res+=f[p][i][j]*(ll)(n-j);
    49       }
    50     }
    51   }
    52   RG int cur=q&1;
    53   for (RG int i=l;i<=r;++i){
    54     res=0;
    55     for (RG int j=r;j>=i;--j)
    56       res+=f[cur][i][j],(sum[j][rk[now]]+=res)%=rhl;
    57   }
    58   return;
    59 }
    60 
    61 int main(){
    62 #ifndef ONLINE_JUDGE
    63   freopen("segment.in","r",stdin);
    64   freopen("segment.out","w",stdout);
    65 #endif
    66   n=gi(),q=gi();
    67   for (RG int i=1;i<=n;++i) a[i]=gi(),s[i]=i,cnt[i]=i*(i+1)>>1;
    68   sort(s+1,s+n+1,cmp); for (RG int i=1;i<=n;++i) rk[s[i]]=i;
    69   for (RG int i=1;i<=n;++i)
    70     for (RG int j=i;j<=n;++j) cal[i][j]=cnt[i-1]+cnt[n-j]+cnt[j-i+1];
    71   for (RG int i=1,l,r;i<=n;++i){
    72     l=r=i; while (l && a[l]<=a[i]) --l;
    73     while (r<=n && a[r]<=a[i]) ++r; solve(l+1,r-1,i);
    74   }
    75   for (RG int i=1;i<=n;++i){
    76     ans=0;
    77     for (RG int j=1;j<=n;++j){
    78       if (!sum[i][j]) continue;
    79       for (RG int k=1;k<j;++k) (sum[i][j]-=sum[i][k])%=rhl;
    80       (ans+=sum[i][j]*(ll)a[s[j]])%=rhl;
    81     }
    82     (ans+=rhl)%=rhl;
    83     if (i!=n) printf("%lld ",ans); else printf("%lld",ans);
    84   }
    85   return 0;
    86 }
  • 相关阅读:
    Eclipse的tab键为4个空格完整方法 附:阿里代码开发规范书
    Linux系统 安装JDK和tomcat
    Window10安装linux
    oracle 查询表重复数据 并 删除保留一条
    Oracle 新增数据 insert into整理
    业需软需word小技巧
    oracle数据库创建表且主键自增
    eclipse更改jdk版本(1.6》1.7 以此类推)
    pytest框架优化——清理历史截图图片和allure报告文件
    allure定制化输出测试报告,让报告锦上添花!
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7306516.html
Copyright © 2020-2023  润新知