UOJ#196. 【ZJOI2016】线段树 概率期望,动态规划

原文链接www.cnblogs.com/zhouzhendong/p/UOJ196.html

题解

先离散化,设离散化后的值域为 $[0,m]$ 。

首先把问题转化一下,变成:对于每一个位置 $i$ ,求出它最终不超过 $j$ 的方案数。

考虑如何求这个东西。

对于一个固定的 $j$ ,考虑一个这样的过程:

初始时,有若干个区间,两两不相交,且区间内的元素都小于等于 $j$ ,而且每一个区间都不能在满足条件的基础上,向左右任意一侧扩张。

考虑其中的一个区间 $[L,R]$ ,如果出现了操作使得它的边界变成了比 $j$ 大的值,那么这个区间会缩小。

考虑对于他的所有子区间 $[x,y]$ ,求出 $q$ 次操作之后, $[L,R]$ 缩小成 $[x,y]$ 的方案数。

这东西显然可以列出 DP 方程:设 $dp[x][i][j]$ 表示当前进行了 $x$ 次操作,初始区间变成 $[i,j]$ 方案数,则:

$$\begin{eqnarray*}dp[x][i][j]&=&\left (\frac{(i-1)i}2 + \frac{(j-i+1)(j-i+2)}2 + \frac {(n-j)(n-j+1)}2 \right )dp[x-1][i][j] \\ &+& \sum_{k=L}^{i-1} dp[x-1][k][j] \cdot (k-1) \\ &+& \sum_{k=j+1}^R  dp[x-1][i][k] \cdot (n-k) \end{eqnarray*}$$

这样的话看上去总的运算量是 $O(n^4)$ 的。

考虑到题目中保证数据随机。

那么,如果对序列建一棵笛卡尔树,那么这个笛卡尔树是基本平衡的,可以近似看做一棵满二叉树。

而我们要求的区间只有 $O(n)$ 个,是对于每一个位置 $i$ ,到它两侧第一个比他大的数之前,这个范围内的区间答案。

这个东西放在笛卡尔树上就是子树的size,而对一个区间进行dp的复杂度是 $O(q\cdot size^2)$ ,又由于这棵笛卡尔树可以近似看做满二叉树,所以求个和就可以发现复杂度总和是 $O(n^2q)$ 的,可以通过此题。

代码

#pragma GCC optimize("Ofast","inline")
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
#define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\For(_v2,L,R)printf("%d ",a[_v2]);puts("");
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> vi;
LL read(){LL x=0,f=0;char ch=getchar();while (!isdigit(ch))f|=ch=='-',ch=getchar();while (isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();return f?-x:x;
}
const int N=405,mod=1e9+7,INF=mod;
void Add(int &x,int y){if ((x+=y)>=mod)x-=mod;
}
void Del(int &x,int y){if ((x-=y)<0)x+=mod;
}
int Pow(int x,int y){int ans=1;for (;y;y>>=1,x=(LL)x*x%mod)if (y&1)ans=(LL)ans*x%mod;return ans;
}
int n,q;
int a[N];
int val[N][N];
vector <int> Ha;
int tmp[N][N];
int dp[2][N][N];
void solve(int L,int R,int t){For(i,L,R)For(j,i,R)dp[0][i][j]=0;dp[0][L][R]=1;For(c,1,q){int _0=(c^1)&1,_1=c&1;For(i,L,R)For(j,i,R)dp[_1][i][j]=(LL)tmp[i][j]*dp[_0][i][j]%mod;For(j,L,R){int s=0;For(i,L,j){Add(dp[_1][i][j],s);Add(s,(LL)dp[_0][i][j]*(i-1)%mod);}}For(i,L,R){int s=0;Fod(j,R,i){Add(dp[_1][i][j],s);Add(s,(LL)dp[_0][i][j]*(n-j)%mod);}}}For(j,L,R){int s=0;For(i,L,j){Add(s,dp[q&1][i][j]);Add(val[i][t],s);}}
}
int main(){n=read(),q=read();For(i,1,n)a[i]=read(),Ha.pb(a[i]);sort(Ha.begin(),Ha.end());Ha.erase(unique(Ha.begin(),Ha.end()),Ha.end());For(i,1,n)a[i]=lower_bound(Ha.begin(),Ha.end(),a[i])-Ha.begin();For(i,1,n)For(j,1,n)tmp[i][j]=(i-1)*i/2+(j-i+1)*(j-i+2)/2+(n-j)*(n-j+1)/2;a[0]=a[n+1]=Ha.size();For(t,0,(int)Ha.size()-1){int L=0,Mx=0;For(R,1,n+1)if (a[R]<=t)Mx=max(Mx,a[R]);else {if (L+1<=R-1){if (Mx<t){For(i,L+1,R-1)Add(val[i][t],val[i][t-1]);}elsesolve(L+1,R-1,t);}L=R,Mx=0;}}For(i,1,n){int ans=0;Fod(j,(int)Ha.size()-1,1)Del(val[i][j],val[i][j-1]);For(j,0,(int)Ha.size()-1)Add(ans,(LL)val[i][j]*Ha[j]%mod);printf("%d ",ans);}puts("");return 0;
}

  

转载于:https://www.cnblogs.com/zhouzhendong/p/UOJ196.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411831.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

又论社区风气, 与程序员是干嘛地的.

为了避免误解, 重新声明一下, 本文纯粹针对"博客园风气如何如何, 博客园的话题如何如何"这些说法, 不含有任何不用基础学习或者必须学习某一方面/最好广泛学习或者必须深钻一门等倾向, 如果有的话说的有偏向性, 请当作一时表达不清. "我可以不同意你的观点, 但我…

在手机上如何用c语言编译器编程,如何用手机进行编程?

这里介绍3种可以在手机上编程的app&#xff0c;分别是c语言编译器(c语言)、AIDE集成开发环境(java)、QPython3(python)&#xff0c;都不需要root&#xff0c;可以直接编写程序并运行&#xff0c;下面我简单介绍一下这3个app的安装和简单使用&#xff0c;主要内容如下&#xff1…

SDOI2014 旅行

传送门 省选前水一发 这题一开始看标签是主席树……后来……这题和主席树有啥关系…… 可以想到对于每种宗教用树剖线段树维护即可。然后因为空间不够要动态开点。然后改宗教&#xff0c;改评级的&#xff0c;把原来的点删了再插一个新点就可以了。查询最大值&#xff0c;和就直…

API函数的调用(包含一个大小写的问题)

遇到问题&#xff1a; 今天做的一个程序要调用AnimateWindow()函数来实现窗口的动画效果&#xff0c;参考书上在类的成员函数中直接调用该函数&#xff0c;没有做任何处理。然而实验时发现编译通不过。 解决过程&#xff1a; 查看MSDN后,发现AnimateWindow()函数说明中…

第一个openGL程序

一、工具的安装 因为要写C程序&#xff0c;为了便捷&#xff0c;这里我安装的Visual Studio&#xff1b; 免费使用90天&#xff01;安装好了之后&#xff0c;我们要为我们的开发安装相应的工具集&#xff1b; 因为我是要在windows上跑的&#xff0c;所以选择如下两个包&#xf…

[转]leo谈“80后”程序员为什么找不到工作?(1)

(应it168约稿写了关于“80后”程序员求职难的文章&#xff0c;我将分三次放在博客上&#xff0c;之后会引用网上的部分批评文章。) 80后的定义应该是&#xff1a;22至27岁之间、受过高等教育、刚刚毕业走向社会或者拥有几年工作经验年轻一代。不可否认&#xff0c;80后已成为职…

c语言斜杠表示除法,[转载]C语言中反斜杠的使用

问题1&#xff1a;#define f(z)(z<2)?(((2-z)*(2-z))*((2-z)*(2-z)))*(((2-z)*(2-z))*((2-z)*(2-z)))/560:0;上面这个*什么意思问题2&#xff1a;一语句printf("a%.2fn,b%.2fn,c%.2fn,d%.2fn,e%.2fn",a,b,c,d,e);不提示错误。换成printf("a%.2fn,b%.2fn,c%.…

SJJG习题一

动态 链 表 的 建 立 1&#xff0e; 修改以下程序&#xff0c;尽可能减少临时空间的占用。即&#xff1a;先判断输入数据的合法性&#xff0c;再为其分配空间。 2&#xff0e; 修改以下程序&#xff0c;把尾插法建立链表改为头插法建立链表…

hdu 2544 最短路

Problem Description在每年的校赛里&#xff0c;所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候&#xff0c;却是非常累的&#xff01;所以现在他们想要寻找最短的从商店到赛场的路线&#xff0c;你可以帮助他们…

华水c语言课程设计,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*************************************************查询函数**********************************************/void search(){int flag,j,x;char w[20];FILE *fp;char v[20];printf("(1)按作者\n");printf("(2)按…

DataGridView 写入到EXCEL

usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Windows.Forms;usingMicrosoft.Office.Interop.Excel;usingSystem.Xml;usingSystem.Xml.Serialization;usingSystem.IO;namespacetxt批处理{ class 保存 { internal static bool 写入E…

Git和Github的学习

来源&#xff1a; 秦时明月NightTiger Git和Github的学习 作者声明&#xff1a;本博客中所写的文章&#xff0c;都是博主自学过程的笔记&#xff0c;参考了很多的学习资料&#xff0c;学习资料和笔记会注明出处&#xff0c;所有的内容都以交流学习为主。有不正确的地方&#xf…

在asp.net中做视频转换,将各种视频文件转换成.flv格式

首先&#xff0c;我们部署一下文件夹.在工程的目录下新建几个文件夹如下图&#xff1a;UpFiles文件夹是要保存你上传的文件&#xff0c;PlayFiles文件夹是用于你转换后保存的文件&#xff08;用于网上播放&#xff09; ImgFile文件夹是保存截取视频文件的图片&#xff0c;然后那…

Android实现支付宝AR功能,Android接入支付宝实现支付功能实例

我本来是想直接讲Android支付这一块的&#xff0c;包括支付宝&#xff0c;微信&#xff0c;其他第三方整合支付等&#xff0c;但是微信开放平台他对我的账号做了限制&#xff0c;所有我今天就先把重心放在支付宝的支付上&#xff0c;也算是写得尽可能详细些吧&#xff0c;毕竟是…