题面在这里

description

已知一个长度为\(n\)的序列\(a_1,a_2,...,a_n\)。

对于每个\(1\le i\le n\),找到最小的非负整数\(p\),

满足对于任意的\(1\le j\le n\),\(a_j\le a_i+p-\sqrt{|i-j|}\)

data range

\[n\le 5\times 10^5,a_i\le 10^9
\]

solution

绝对值怎么办?

我们先从左到右\(DP\ j< i\)的部分(此时有\(|i-j|=i-j\)),

再右到左\(DP\ j> i\)的部分(此时有\(|i-j|=j-i\));

那么我们现在考虑这个式子:

\[f[i]=max_{j=1}^{i-1}(a[j]-a[i]+\sqrt{i-j})
\]

对于每一个相同的\(i\),

记\(w[j]=\sqrt{i-j}\),那么我们很容易发现这个函数是凸函数

对于两个决策\(j<k\),当\((j-k)\)一定时,我们发现\(w[j]-w[k]\)随着\(i\)的递增而递减

而对于这两个决策,\(j\)比\(k\)优当且仅当对于\(j<k<i\le n\),

\[a[j]+\sqrt{i-j}\ge a[k]+\sqrt{i-k}
\]

\[g[j,k]=a[j]-a[k]+w[j]-w[k]\ge 0
\]

当\(i\)递增时,\(g[j,k]\)这个函数单调递减,那么存在一个分界点\(i'\),

使得当\(i\le i'\)时,\(g[j,k]\ge 0\)(\(j\)更优),当\(i\ge i'\)时,\(g[j,k]\le 0\)(\(k\)更优);

那么我们知道这个\(DP\)方程具有决策单调性

具体如何实现?

考虑相邻的两个决策\(j,k\),

由于上面的性质,我们可以二分出这两个决策的分界点\(t[j,k]\);

对于相邻的三个决策\(x,y,z\),如果\(t[x,y]\ge t[y,z]\)那么决策\(y\)是没有用的可以扔掉

考虑维护一个单调队列,存放所有合法的决策;

由于我们在维护的同时\(i\)是变化的,

因此我们需要求出每个决策此时转移最优的区间

即单调队列存放的元素为\((pos,l_{pos},r_{pos})\)(注意\(pos < l_{pos}\le r_{pos}\))

当加入新决策\(j\)时,考虑队尾的决策\((k,l_k,r_k)\);

如果\(j\)总是比\(k\)要劣(在这里指对于\(i=n\)仍有\(a[j]+\sqrt{i-j}\le a[k]+\sqrt{i-k}\)),

则不考虑决策\(j\);

否则(此时\(r_j=n\)),如果对于\(i=l_k\)有\(a[j]+\sqrt{i-j}\ge a[k]+\sqrt{i-k}\),

一直弹掉队尾决策并考虑队尾的前一个决策,如果队列为空则压入\((j,j,n)\);

否则(此时存在一个决策\(k\)无法被弹出),考虑二分决策\(k\)和\(j\)的分界点\(mid\)

(本人的定义是,对于\(i\le mid\),有\(a[k]+\sqrt{i-k}> a[j]+\sqrt{i-j}\)),

之后将\(r_k\)修改为\(mid\),压入决策\((j,mid,n)\)。

il dd calc(int j,int i){return a[j]-a[i]+sqrt(i-j);}
//计算j转移至i时对应的DP值
il int divide(int k,int j,int l,int r){
RG int mid,ans=l;
while(l<=r){
mid=(l+r)>>1;
if(calc(k,mid)>calc(j,mid))
ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
//二分分界点
il void push(int i){
if(calc(Qx[R],n)>calc(i,n))return;
while(calc(Qx[R],Ql[R])<calc(i,Ql[R])&&L<=R)R--;
if(L>R){Ql[++R]=i;Qr[R]=n;Qx[R]=i;return;}
Qr[R]=divide(Qx[R],i,Ql[R],Qr[R]);
R++;Ql[R]=Qr[R-1]+1;Qr[R]=n;Qx[R]=i;
}
//插入新决策

当要查询位置\(pos\)时,直接从队头开始查找,

如果队首决策\((k,l_k,r_k)\)中\(r_k<pos\)或队首决策劣于队首后决策则将其弹出;

否则,将其作为此次查询的答案

il int pop(int i){
while(Qr[L]<i||(L<R&&calc(Qx[L],i)<calc(Qx[L+1],i)))L++;
return Qx[L];
}
//查询答案

这里是总的\(DP\)模板

il void DP(int *a,int *p,int n){
L=0;R=-1;
for(RG int i=1;i<=n;i++){
if(i!=1)p[i]=ceil(calc(pop(i),i));Ql[L]=i;push(i);
//答案为非负整数,这里做了上取整
}
}
//DP序列

code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mp make_pair
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int N=1000000;
const int inf=1e9+7;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
} il void file(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
} int n,a[N],p[N],s[N];
int Qx[N],Ql[N],Qr[N],L,R; il dd calc(int j,int i){return a[j]-a[i]+sqrt(i-j);}
//计算j转移至i时对应的DP值
il int divide(int k,int j,int l,int r){
RG int mid,ans=l;
while(l<=r){
mid=(l+r)>>1;
if(calc(k,mid)>calc(j,mid))
ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
//二分分界点
il void push(int i){
if(calc(Qx[R],n)>calc(i,n))return;
while(calc(Qx[R],Ql[R])<calc(i,Ql[R])&&L<=R)R--;
if(L>R){Ql[++R]=i;Qr[R]=n;Qx[R]=i;return;}
Qr[R]=divide(Qx[R],i,Ql[R],Qr[R]);
R++;Ql[R]=Qr[R-1]+1;Qr[R]=n;Qx[R]=i;
}
//插入新决策
il int pop(int i){
while(Qr[L]<i||(L<R&&calc(Qx[L],i)<calc(Qx[L+1],i)))L++;
return Qx[L];
}
//查询答案
il void DP(int *a,int *p,int n){
L=0;R=-1;
for(RG int i=1;i<=n;i++){
if(i!=1)p[i]=ceil(calc(pop(i),i));Ql[L]=i;push(i);
}
}
//DP序列
int main()
{
n=read();
for(RG int i=1;i<=n;i++)a[i]=read();
DP(a,p,n);reverse(a+1,a+1+n);DP(a,s,n);
for(RG int i=1;i<=n;i++)
printf("%d\n",max(0,max(p[i],s[n-i+1])));
//记得答案是非负整数
return 0;
}

[POI2011]Lightning Conductor的更多相关文章

  1. [bzoj 2216] [Poi2011] Lightning Conductor

    [bzoj 2216] [Poi2011] Lightning Conductor Description 已知一个长度为n的序列a1,a2,-,an. 对于每个1<=i<=n,找到最小的 ...

  2. 【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性

    [BZOJ2216][Poi2011]Lightning Conductor Description 已知一个长度为n的序列a1,a2,...,an.对于每个1<=i<=n,找到最小的非负 ...

  3. P3515 [POI2011]Lightning Conductor(决策单调性分治)

    P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下 ...

  4. 【BZOJ】2216: [Poi2011]Lightning Conductor

    题意 给一个长度为\(n\)的序列\(a_i\),对于每个\(1 \le i \le n\),找到最小的非负整数\(p\)满足 对于任意的\(j\), \(a_j \le a_i + p - \sqr ...

  5. BZOJ2216 : [Poi2011]Lightning Conductor

    $f[i]=\max(a[j]+\lceil\sqrt{|i-j|}\rceil)$, 拆开绝对值,考虑j<i,则决策具有单调性,j>i同理, 所以可以用分治$O(n\log n)$解决. ...

  6. 洛谷P3515 [POI2011]Lightning Conductor(动态规划,决策单调性,单调队列)

    洛谷题目传送门 疯狂%%%几个月前就秒了此题的Tyher巨佬 借着这题总结一下决策单调性优化DP吧.蒟蒻觉得用数形结合的思想能够轻松地理解它. 首先,题目要我们求所有的\(p_i\),那么把式子变一下 ...

  7. bzoj 2216 [Poi2011]Lightning Conductor——单调队列+二分处理决策单调性

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2216 那个关于位置的代价是带根号的,所以随着距离的增加而增长变慢:所以靠后的位置一旦比靠前的 ...

  8. BZOJ2216 [Poi2011]Lightning Conductor 【决策单调性dp】

    题目链接 BZOJ2216 题解 学过高中数学都应知道,我们要求\(p\)的极值,参变分离为 \[h_j + sqrt{|i - j|} - h_i \le p\] 实际上就是求\(h_j + sqr ...

  9. BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】

    Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...

  10. bzoj2216: [Poi2011]Lightning Conductor(分治决策单调性优化)

    每个pi要求 这个只需要正反DP(?)一次就行了,可以发现这个是有决策单调性的,用分治优化 #include<iostream> #include<cstring> #incl ...

随机推荐

  1. npm run build打包后自定义动画没有执行

    问题描述:在vue项目中,当你自己写了一些自定义动画效果,然后你npm run build打包项目放到线上环境后,发现动画并没有效果. 解决办法:在vue项目中找到build文件夹下的vue-load ...

  2. 微信小程序 嵌套循环

    前言 入门教程之列表渲染多层嵌套循环,目前官方的文档里,主要是一维数组列表渲染的案例,还是比较简单单一,给刚入门的童鞋还是无从入手的感觉. <view wx:for="{{items} ...

  3. 链栈的c++实现

    2013-08-30 20:58 1876人阅读 评论(0) 收藏 举报 链栈是借用单链表实现的栈.其不同于顺序栈之处在于: 1.链栈的空间是程序运行期间根据需要动态分配的,机器内存是它的上限.而顺序 ...

  4. Kubernetes-深入分析集群安全机制(3.6)

    集群的安全性主要考虑以下几个方面: 容器与所在宿主机的隔离: 限制容器给基础设施及其他容器带来消极影响的能力: 最小权限原则--合理限制所有组件的权限,确保组件只执行它被授权的行为,通过限制单个组件的 ...

  5. 前端面试题目汇总摘录(HTML 和 CSS篇)

    温故而知新,保持空杯心态 HTML 和 CSS 你做的页面在哪些浏览器测试过?这些浏览器的内核分别是什么 浏览器名称 内核 IE trident Firefox(火狐) gecko Safari we ...

  6. 20145202马超 2006-2007-2 《Java程序设计》第2周学习总结

    20145202马超 2016-2017-2 <Java程序设计>第2周学习总结 教材学习内容总结 第三章主要讲了各种变量的设置以及流程控制,基本上都和c是一样的.print是不太一样的, ...

  7. c/c++ 随机数生成

    当程序需要一个随机数时有两种情况下使用: 1.程序中只需使用一次随机数,则调用rand()函数即可 2.程序需要多次使用随机数,那么需要使用srand()函数生成随机数种子在调用rand()函数保证每 ...

  8. Android之线程安全的单例模式,Adapter注意事项之引用传值

    线程安全的单例模式单位模式一般写法如下: public static FestivalLab mInstance; private FestivalLab() { } public static Fe ...

  9. 安装mathtype出问题卸载后 office2016打开mathtype弹错误窗口

    解决方法:找到 C:\Program Files (x86)\Microsoft Office\root\Office16\STARTUP目录下的MathType Commands 6 For Wor ...

  10. fildder抓包工具详解

    fildder页面介绍名称和含义 名称 含义 # 抓取HTTP Request的顺序,从1开始,以此递增 Result HTTP状态码 Protocol 请求使用的协议,如HTTP/HTTPS/FTP ...