BZOJ4574 [Zjoi2016]线段树
比较厉害的dp.
网上题解都是利用了随机的条件,用了一个$O(n^4)$的dp,这里简单说一下。
用f(x,i,l,r)表示经过前i轮操作,[l,r]的所有数<=x,且l-1和r+1都>x的方案数。
转移:f(x,i,l,r)=f(x,i-1,l,r)*g(l,r)+f(x,i-1,j,r)*(j-1)+f(x,i-1,l,k)*(n-k),j<l,k>r
其中,g(l,r)=l*(l-1)/2+(r-l+1)*(r-l+2)/2+(n-r)*(n-r+1)/2
用个前缀和优化一下转移即可。
设h(x,i)表示最终位置i的数<=x的方案数,h(x,i)=$\sum_{l=1}^i\sum_{r=i}^nf(x,q,l,r)$
ans(i)=$\sum_xx*(h(x,i)-h(x-1,i))$
但是这样的做法不够优秀,有没有不利用随机的特性,严格$O(n^3)$的做法呢?
答案是有的。
其实很简单,观察发现转移的时候第一维是固定的,我们可以直接用dp(i,l,r)表示各种x的贡献和。
把上面ans(i)中的h展开,发现dp(i,l,r)=$\sum_x-f(x,i,l,r)$
转移没有变化,但初始化有变化。
初始化时的dp值怎么计算呢?
发现对于一段极长的区间[l,r],dp(0,l,r)=max(a(l)...a(r))-min(a(l-1),a(r+1)),对于非极长的区间dp(0,l,r)=0
发现#define一个for真好用233.
#include <cstdio>
#include <algorithm>
#define F(i,l,r) for(int i=l;i<=r;i++) const int N=,p=1e9+;
int n,q,a[N],f[][N][N],g[N][N],s1[][N][N],s2[][N][N]; int main() {
scanf("%d%d",&n,&q),a[]=a[n+]=1e9+;
F(i,,n) scanf("%d",&a[i]);
F(i,,n) {
int r=;
F(j,i,n) {
g[i][j]=i*(i-)/+(n-j)*(n-j+)/+(j-i+)*(j-i+)/,r=std::max(r,a[j]);
if(i==&&j==n) f[][i][j]=r;
else if(a[i-]>r&&a[j+]>r) f[][i][j]=(r-std::min(a[i-],a[j+])+p)%p;
}
}
F(i,,q) {
int s=i&,t=(i&)^;
F(j,,n) for(int k=n;k>=j;k--) s2[t][j][k]=(s2[t][j][k+]+1LL*f[t][j][k]*(n-k))%p;
F(j,,n) F(k,j,n) s1[t][j][k]=(s1[t][j-][k]+1LL*f[t][j][k]*(j-))%p,f[s][j][k]=(1LL*f[t][j][k]*g[j][k]+s1[t][j-][k]+s2[t][j][k+])%p;
}
F(i,,n) {int a1=; F(j,,i) F(k,i,n) a1=(a1+f[q&][j][k])%p; printf("%d%c",a1," \n"[i==n]);}
return ;
}
BZOJ4574 [Zjoi2016]线段树的更多相关文章
- bzoj4574:Zjoi2016线段树 dp
传送门 题解传送门 //Achen #include<algorithm> #include<iostream> #include<cstring> #includ ...
- bzoj 4574: [Zjoi2016]线段树
Description 小Yuuka遇到了一个题目:有一个序列a_1,a_2,?,a_n,q次操作,每次把一个区间内的数改成区间内的最大值,问 最后每个数是多少.小Yuuka很快地就使用了线段树解决了 ...
- 【UOJ#196】【BZOJ4574】[Zjoi2016]线段树
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4574 http://uoj.ac/problem/196 考虑数字随机并且值域够大,我们 ...
- Luogu3352 ZJOI2016 线段树 概率、区间DP
传送门 考虑对于每一个位置\(i\),计算所有可能的结果出现的概率. 定义一个区间\([l,r]\)为对于\(x\)的极大区间,当且仅当\(\max \limits _{i=l}^r \{a_i\} ...
- 【ZJOI2016】线段树
[ZJOI2016]线段树 ZJOI的题神啊. 我们考虑计算每个位置\(p\),它在操作过后变成第\(x\)个数的操作序列数. 我们枚举\(x\).我们先得到了\(L_x,R_x\)表示最左边比\(x ...
- @loj - 2093@ 「ZJOI2016」线段树
目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Yuuka 遇到了一个题目:有一个序列 a1,a2,..., ...
- bzoj3932--可持久化线段树
题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
随机推荐
- iOS 播放音频的几种方法
Phone OS 主要提供以下了几种播放音频的方法: System Sound Services AVAudioPlayer 类 Audio Queue Services OpenAL 1. Syst ...
- 超绚丽CSS3多色彩发光立方体旋转动画
CSS3添加了几个动画效果的属性,通过设置这些属性,可以做出一些简单的动画效果而不需要再去借助JavaScript.css3动画的属性主要分为三类:transform.transition以及anim ...
- js实现短暂提示框
业务场景:当鼠标移入某元素时,显示提示框进行介绍.当鼠标移除时,会自动消失.引入ToolTip.js和ToolTip.css 主方法:ToolTip.show(需要提示的元素id, 随意不重复即可, ...
- [译]RabbitMQ教程C#版 - 工作队列
先决条件 本教程假定RabbitMQ已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难,可以 ...
- 完美解决ubuntu Desktop 16.04 中文版firefox在非root用户不能正常启动的问题
ubuntu安装好后,默认安装有firefox浏览器,不过,非root的账户登录,双击firefox图标,居然出现如下提示:Your Firefox profile cannot be loaded. ...
- 一种dubbo逻辑路由方案
背景介绍 现在很多的公司都在用dubbo.springcloud做为服务化/微服务的开发框架,服务化之后应用越来越多,链路越来越长,服务环境的治理变的很困难.比如:研发团队的人很多的,同时有几个分支在 ...
- cv2.cornerHarris()详解 python+OpenCV 中的 Harris 角点检测
参考文献----------OpenCV-Python-Toturial-中文版.pdf 参考博客----------http://www.bubuko.com/infodetail-2498014. ...
- Linux下安装jmeter
一.用Xftp上传apache-jmeter-2.13.tgz到Linux系统里 二.解压apache-jmeter-2.13.tgz,tar xzfv apache-jmeter-2.13.tgz ...
- Cookie、Session登陆验证相关介绍和用法
一.Cookie和Session 首先.HTTP协议是无状态的:所谓的无状态是指每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应直接影响,也不会直接 ...
- 记录安装centos6.5的几个要紧步骤
1.安装新系统 因为是服务器,不是普通电脑,貌似对usb支持不好,所以用的光盘安装. centos 6.5 64位 2.跳过测试 3.服务器语言 选择english,键盘是english.US 4.选 ...