洛谷P3515 [POI2011]Lightning Conductor(动态规划,决策单调性,单调队列)
疯狂%%%几个月前就秒了此题的Tyher巨佬
借着这题总结一下决策单调性优化DP吧。蒟蒻觉得用数形结合的思想能够轻松地理解它。
首先,题目要我们求所有的\(p_i\),那么把式子变一下
\]
\]
绝对值看着很不爽,我们把它拆开
\]
单独看前一部分
\]
很明显是个要用决策单调性优化的式子。把序列翻转以后,后一部分的算法和前面是一样的,所以只讨论前一部分了。
对于每个\(j\),把\(a_j+\sqrt{i-j}\)看成关于\(i\)的函数\(f_j\)。我们要做的就是在所有\(j\leq i\)的函数中找到最值。比如样例:

观察发现,真正有用的函数只有最上面那个!然而实际情况比这个稍复杂些。sqrt的增速是递减的,因此可能存在一个\(j\)比较小的函数,在某一时刻被\(j\)比较大的函数反超。我们大概需要维护这样的若干个函数:

我们用队列实现决策二分栈(不懂的可以参考一下蒟蒻的blog),按\(j\)从小到大依次维护这些函数。显然,对于其中任意两个相邻的函数\(f_t,f_{t+1}\),它们都有一个临界值\(k_{t,t+1}\)。显然序列中的\(k_{1,2},k_{2,3}...\)也要严格递增。否则,如果\(k_{t,t+1}\ge k_{t+1,t+2}\),可以想象\(f_{t+1}\)根本没有用。
先for一遍\(i\),我们尝试着把\(f_i\)加入队列。这时候为了保证\(k\)递增,设队尾决策为\(t\),我们判断,如果\(k_{t-1,t}\ge k_{t,i}\)(此时会有\(f_t(k_{t-1,t})\le f_i(k_{t-1,t})\)),那么\(t\)没用,出队。
该出去的都出去后,\(i\)就可以加入队尾了。这时候可以来求\(p_i\)了。我们检查一下队首决策\(h\),如果\(t_{h,h+1}\le i\),说明\(h\)的巅峰时刻已经过去,出队。最后队首就是所有函数中的最大值。
貌似并没有用到什么三元组啊qwq
update:感谢孤独·粲泽的指正,二分上下界确实该调调
不过还是没有用到什么三元组啊qwq,蒟蒻之前都把临界值\(k\)存下了,直接用就可以啦
#include<bits/stdc++.h>
#define RG register
#define R RG int
#define G if(++ip==iend)fread(ip=buf,1,N,stdin)
#define calc(i,j) a[j]+sq[i-j]//计算函数值
using namespace std;
const int N=5e5+9;
char buf[N],*iend=buf+N,*ip=iend-1;
int n,a[N],q[N],k[N];
double p[N],sq[N];
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
inline void chkmx(RG double&x,RG double y){
if(x<y)x=y;
}
inline int bound(R x,R y){//二分临界值k
R l=y,r=k[x]?k[x]:n,m,ret=r+1;//控制二分上下界
while(l<=r){
m=(l+r)>>1;
if(calc(m,x)<=calc(m,y))
ret=m,r=m-1;
else l=m+1;
}
return ret;
}
void work(){
for(R h=1,t=0,i=1;i<=n;++i){
while(h<t&&calc(k[t-1],q[t])<calc(k[t-1],i))--t;//维护k单调
k[t]=bound(q[t],i);q[++t]=i;
while(h<t&&k[h]<=i)++h;//将已经不优的决策出队
chkmx(p[i],calc(i,q[h]));//因为做两遍所以取max
}
}
int main(){
n=in();
R i,j;
for(i=1;i<=n;++i)
a[i]=in(),sq[i]=sqrt(i);
work();
for(i=1,j=n;i<j;++i,--j)//序列翻转
swap(a[i],a[j]),swap(p[i],p[j]);
work();
for(R i=n;i;--i)//翻转过了所以要倒着输出
printf("%d\n",max((int)ceil(p[i])-a[i],0));
return 0;
}
洛谷P3515 [POI2011]Lightning Conductor(动态规划,决策单调性,单调队列)的更多相关文章
- 洛谷P3515 [POI2011]Lightning Conductor(决策单调性)
题意 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j)) ...
- P3515 [POI2011]Lightning Conductor(决策单调性分治)
P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下 ...
- 【洛谷3515】[POI2011] Lightning Conductor(决策单调性)
点此看题面 大致题意: 给你一个序列,对于每个\(i\)求最小的自然数\(p\)使得对于任意\(j\)满足\(a_j\le a_i+p-\sqrt{|i-j|}\). 证明单调性 考虑到\(\sqrt ...
- BZOJ2216 [Poi2011]Lightning Conductor 【决策单调性dp】
题目链接 BZOJ2216 题解 学过高中数学都应知道,我们要求\(p\)的极值,参变分离为 \[h_j + sqrt{|i - j|} - h_i \le p\] 实际上就是求\(h_j + sqr ...
- BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】
Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...
- BZOJ2216: [Poi2011]Lightning Conductor(DP 决策单调性)
题意 题目链接 Sol 很nice的决策单调性题目 首先把给出的式子移项,我们要求的$P_i = max(a_j + \sqrt{|i - j|}) - a_i$. 按套路把绝对值拆掉,$p_i = ...
- bzoj 2216: [Poi2011]Lightning Conductor【决策单调性dp+分治】
参考:https://blog.csdn.net/clove_unique/article/details/57405845 死活不过样例看了题解才发现要用double.... \[ a_j \leq ...
- P3515 [POI2011]Lightning Conductor[决策单调性优化]
给定一序列,求对于每一个$a_i$的最小非负整数$p_i$,使得$\forall j \neq i $有$ p_i>=a_j-a_i+ \sqrt{|i-j|}$. 绝对值很烦 ,先分左右情况单 ...
- P3515 [POI2011]Lightning Conductor
首先进行一步转化 $a_j \leq a_i + q - sqrt(abs(i - j))$ $a_i + q \geq a_j + sqrt(abs(i-j))$ 即 $q = max (a_j + ...
随机推荐
- Luogu3175 HAOI2015 按位或 min-max容斥、高维前缀和、期望
传送门 套路题 看到\(n \leq 20\),又看到我们求的是最后出现的位置出现的时间的期望,也就是集合中最大值的期望,考虑min-max容斥. 由\(E(max(S)) = \sum\limits ...
- 重写Override ToString()方法
使用一个小例子来演示: 创建一个普通类别: class Ax { private int _ID; public int ID { get { return _ID; } set { _ID = va ...
- Quartz.Net分布式任务管理平台(续)
感谢@Taking园友得建议,我这边确实多做了一步上传,导致后面还需处理同步上传到其他服务器来支持分布式得操作.所有才有了上篇文章得完善. 首先看一下新的项目结构图: 这个图和上篇文章中 ...
- 从源码的角度看 React JS 中批量更新 State 的策略(上)
在之前的文章「深入理解 React JS 中的 setState」与 「从源码的角度再看 React JS 中的 setState」 中,我们分别看到了 React JS 中 setState 的异步 ...
- css-preprocessors
what ? 预处理器是css 能够使用 变量.操作符.函数.mixins.interpolations 等类似于js 功能的一种语言. 目前比较常用是三种:SASS.less .stylus . W ...
- 【个人博客作业II】有关代码规范问题的讨论
参考课程辅导书<构建之法>可以知道,程序的代码规范常指代码风格规范和代码设计规范两个方面,其中:代码风格规范包括(缩进,行宽,括号,断行与空白行,分行,命名,下划线,大小写,注释这几个部分 ...
- 个人作业 Last
对M1/M2阶段的总结 M1阶段的总结反思见我以前的博客,我以前曾经写过.现附上链接.http://www.cnblogs.com/jirufeng/p/4990245.html M2阶段主要是对我们 ...
- jdk自带的jvisualvm-监控远程linux
简介 jdk有好多自带的工具比如jconsole.jvisualvm.jstatd等 Windows的路径:%JAVA_HOME/bin/目录下,配置好环境变量直接用cmd执行jvisualvm命令即 ...
- 在Java中执行Tomcat中startup.bat
问题:更改数据库时,需要重启Tomcat服务器,才能把更改后的数据加载到项目中.于是想每次更改数据库时,都调用Java方法,重启Tomcat 代码: Process process = Runtime ...
- github的使用心得
我的github地址:https://github.com/gaino1/test GitHub 是一个用于使用Git版本控制系统的项目的基于互联网的存取服务. GitHub可以托管各种git库,并提 ...