P3352 [ZJOI2016]线段树

(^ w ^)

题目描述
小Yuuka遇到了一个题目:有一个序列a_1,a_2,?,a_n,q次操作,每次把一个区间内的数改成区间内的最大值,问最后每个数是多少。小Yuuka很快地就使用了线段树解决了这个问题。

于是充满智慧的小Yuuka想,如果操作是随机的,即在这q次操作中每次等概率随机地选择一个区间l,r,然后将这个区间内的数改成区间内最大值(注意这样的区间共有(n(n+1))/2个),最后每个数的期望大小是多少呢?小Yuuka非常热爱随机,所以她给出的输入序列也是随机的(随机方式见数据规模和约定)。对于每个数,输出它的期望乘((n(n+1))/2)q再对109+7取模的值。

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

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

输入输出样例
输入样例#1:

5 5
1 5 2 3 4

输出样例#1:

3152671 3796875 3692207 3623487 3515626

题解

换而言之就是求每个点所有区间组合之后结果之和。

我们注意到这显然是一个dp题,所以要思考一个状态之和。

fj,i,x,y\ f_{j,i,x,y} fj,i,x,y​表示进行i\ i i此操作后,区间[x,y]\ [x,y] [x,y]内,所有元素≤j\ \le j ≤j,ay+1,ax−1≥j\ a_{y+1},a_{x-1} \ge j ay+1​,ax−1​≥j的方案数,gi,j\ g _{i,j} gi,j​表示不横跨i\ i i,j\ j j的区间的方案数。
我们可得一下dp式。
fs,i,x,y=fs,i−1,x,y⋅gx,y+∑j=1y−1fs,i−1,j,y⋅(j−1)+∑k=x+1nfs,i−1,x,k⋅(n−k)gx,y=x(x−1)2+(y−x+1)(y−x+2)2+(n−y)(n−y+1)2f_{s,i,x,y}=f_{s,i-1,x,y} \cdot g_{x,y} + \sum_{j=1}^{y-1} f_{s,i-1,j,y} \cdot (j-1) +\sum_{k=x+1}^{n} f_{s,i-1,x,k} \cdot (n-k) \\ g_{x,y}= \frac{x(x-1)}{2} + \frac{(y-x+1)(y-x+2)}{2} + \frac{(n-y)(n-y+1)}{2} fs,i,x,y​=fs,i−1,x,y​⋅gx,y​+j=1∑y−1​fs,i−1,j,y​⋅(j−1)+k=x+1∑n​fs,i−1,x,k​⋅(n−k)gx,y​=2x(x−1)​+2(y−x+1)(y−x+2)​+2(n−y)(n−y+1)​

由此可以想到一个O(n4\ n^{4} n4)的算法:离散化之后枚举,这显然是不好过的。然而有人卡过了。所以我们要像一个更优的算法。
我们发现第一维是固定的,式子也几乎不和第一维相关,所以我们改用其他状态。

fi,x,y\ f_{i,x,y} fi,x,y​表示所有的第一维方案数之和。

转移式与之前完全相同:

fi,x,y=fi−1,x,y⋅gx,y+∑j=1y−1fi−1,j,y⋅(j−1)+∑k=x+1nfi−1,x,k⋅(n−k)gx,y=x(x−1)2+(y−x+1)(y−x+2)2+(n−y)(n−y+1)2f_{i,x,y}=f_{i-1,x,y} \cdot g_{x,y} + \sum_{j=1}^{y-1} f_{i-1,j,y} \cdot (j-1) +\sum_{k=x+1}^{n} f_{i-1,x,k} \cdot (n-k) \\ g_{x,y}= \frac{x(x-1)}{2} + \frac{(y-x+1)(y-x+2)}{2} + \frac{(n-y)(n-y+1)}{2} fi,x,y​=fi−1,x,y​⋅gx,y​+j=1∑y−1​fi−1,j,y​⋅(j−1)+k=x+1∑n​fi−1,x,k​⋅(n−k)gx,y​=2x(x−1)​+2(y−x+1)(y−x+2)​+2(n−y)(n−y+1)​

复杂度O(n3\ n^{3} n3).

AC代码

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
int n,q,a[410];
long long f[2][410][410],sum1[2][410][410],sum2[2][410][410],g[410][410];
bool cmp(const int &x,const int &y)
{return a[x]<a[y];
}
int main()
{scanf("%d%d",&n,&q);int i=1,r=0,j=0,k=0;a[0]=2000000000;a[n+1]=2000000000;while(i<=n){scanf("%d",&a[i]);++i;}i=1;while(i<=n){r=0;j=i;while(j<=n){g[i][j]=i*(i-1)/2+(n-j)*(n-j+1)/2+(j-i+1)*(j-i+2)/2;r=max(r,a[j]);if((i==1)&&(j==n)) f[0][i][j]=r;else if((a[i-1]>r)&&(a[j+1]>r)) f[0][i][j]=(r-min(a[i-1],a[j+1])+mod)%mod;++j;}++i;}int now=1,last=0;i=1;while(i<=q){j=1;while(j<=n){k=n;while(k>=j){sum2[last][j][k]=(sum2[last][j][k+1]+f[last][j][k]*(n-k))%mod;--k;}++j;}j=1;while(j<=n){k=j;while(k<=n){sum1[last][j][k]=(sum1[last][j-1][k]+f[last][j][k]*(j-1))%mod;f[now][j][k]=(f[last][j][k]*g[j][k]+sum1[last][j-1][k]+sum2[last][j][k+1])%mod;++k;}++j;}now^=1;last^=1;++i;}long long ss=0;i=1;while(i<=n){ss=0;j=1;while(j<=i){k=i;while(k<=n){ss+=f[q&1][j][k];ss%=mod;++k;}++j;}printf("%lld ",ss);++i;}return 0;
}
/*
1996年:东方灵异传(TOH1)
1997年:东方封魔录(TOH2)
1997年:东方梦时空(TOH3)
1998年:东方幻想乡(TOH4)
1998年:东方怪绮谈(TOH5)
2002年:东方红魔乡(TOH6)
2003年:东方妖妖梦(TOH7)
2004年:东方萃梦想(TOH7.5)
2004年:东方永夜抄(TOH8)
2005年:东方花映冢(TOH9)
2005年:东方文花帖(TOH9.5)
2007年:东方风神录(TOH10)
2008年:东方绯想天(TOH10.5)
2008年:东方地灵殿(TOH11)
2009年:东方星莲船(TOH12)
2009年:东方非想天则(TOH12.3)
2010年:东方文花帖DS(TOH12.5)
2010年:东方三月精(TOH12.8)
2011年:东方神灵庙(TOH13)
2013年:东方心绮楼(TOH13.5)
2013年:东方辉针城(TOH14)
2014年:弹幕天邪鬼(TOH14.3)
2014年:东方深秘录(TOH14.5)
2015年:东方绀珠传(TOH15)
2017年:东方凭依华(TOH15.5)
2017年:东方天空璋(TOH16)
*/

洛谷P3352 [ZJOI2016]线段树相关推荐

  1. 洛谷 p3372 模板-线段树 1

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个 ...

  2. 洛谷 - P1198 - 最大数 - 线段树

    https://www.luogu.org/problemnew/show/P1198 要问区间最大值,肯定是要用线段树的,不能用树状数组.(因为没有逆元?但是题目求的是最后一段,可以改成类似前缀和啊 ...

  3. 【洛谷 3372】线段树 1

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含 ...

  4. 【洛谷】【线段树】P3353 在你窗外闪耀的星星

    [题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...

  5. 洛谷P4114 Qtree1(树链剖分+线段树)

    传送门 LCT秒天秒地用什么树剖 这题可以算是树剖的比较裸的题目了 把每一条边的权值下放到他两边的点中深度较深的那个 然后直接用树剖+线段树带进去乱搞就可以了 1 //minamoto 2 #incl ...

  6. 专题·树链剖分【including 洛谷·【模板】树链剖分

    初见安~~~终于学会了树剖~~~ [兴奋]当初机房的大佬在学树剖的时候我反复强调过:"学树剖没有前途的!!!" 恩.真香. 一.重链与重儿子 所谓树剖--树链剖分,就是赋予一个链的 ...

  7. Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)

    题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...

  8. 洛谷 - P2617 Dynamic Rankings(树状数组套主席树)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a,再给出 m 次操作: Q l r k:返回区间 [ l , r ] 内第 k 大的数 C x y:令 a[ x ] = y 题目分析:其实 ...

  9. 洛谷 P2486 [SDOI2011]染色 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 PushDown与Update Q AC代码 总结与拓展 题面 题目链接 P2486 ...

最新文章

  1. 《西河大鼓——夸轿车》(唱词文本)
  2. SHELL脚本--简介
  3. python中read()、readline()、readlines()函数
  4. 拍摄中如何判断灰度等级_如何判断电力铁塔的电压等级?每个人都应知道
  5. 时光老人的飞鸽传书下载
  6. H2O_Hyper_V-master网页端管理程序源码
  7. 一线互联网企业面试题总结(帮你成功拿到offer)
  8. linux磁盘扩容_超详尽!Linux云服务器存储扩容实操
  9. Spring学习总结(27)——Spring常用注解再总结
  10. C语言学习笔记---指针
  11. html js获取本地ip,在js获取本地IP地址
  12. ubuntu更改ip地址 网官 dns,使ubuntu的ip地址每次启动都是固定
  13. python 操作ps脚本_Python实现PS图像调整颜色梯度效果示例
  14. 关于大一c语言期中考试总结
  15. 点击链接重定向跳转微信公众号关注页、微信关注链接
  16. 怎么把Excel表格旋转90°显示
  17. 喜马拉雅全站音频爬取
  18. 戴尔笔记本提示“您已插入低瓦数电源适配器 在bios设置中可以禁用此警告”
  19. 《香帅金融学讲义》读书笔记
  20. 中国的手机号码格式化/分类工具

热门文章

  1. 敏捷项目管理21天学习计划--敏捷生命周期
  2. 三国志战略版赤壁之战如何开荒?
  3. vue 做登陆页面 ( 登陆成功后去掉注册和登陆按钮 显示用户名)
  4. 梧桐树王牌产品金玉满堂增额终身寿险下架在即,资产焦虑就买它
  5. 顶配梧桐树金玉满堂增额终身寿险,对抗“资产荒”的高增长神器
  6. tomca的用户设置
  7. 【4 于博士Cadence SPB15.7 快速入门视频】建立不规则SOIC封装NE5532
  8. 干货!网络推断与数据驱动的影响力最大化问题
  9. 年轻人应不应该买房 如何买
  10. 计算机毕业设计SSM鞍山丘比特房屋租赁管理系统【附源码数据库】