P3515 [POI2011]Lightning Conductor (四边形不等式优化)
这道题很容易看出来二维的转移方程,只要移一下项就行
但是二维的显然不行,这个数据范围,一看就是nlogn的复杂度,因此想到优化,我们看到这个表达式,只能想到是否有四边形不等式优化的可能性
因此去证明一下,因为四边形不等式的决策单调性都是根据min来证的,我们把max取反就变成min,然后根据定理求导一下发现符合决策单调性
对于一维的来说,一般有两种方法实现这个性质,我这里采用的是单调队列的方法,我们知道既然符合单调性,那么答案肯定是一个不降序列
每个决策点都包含一段区间,因此队头就是答案,在插入当前决策点的时候,对队尾进行分析就行
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e5+10; int f[2][N]; struct node{ int l,r,p; }; node q[N]; int a[N],n; double check(int i,int j){ return -a[i]+a[j]+sqrt(i-j); } int find(int l,int r,int i,int j){ while(l<r){ int mid=l+r>>1; if(check(mid,i)>check(mid,j)) r=mid; else l=mid+1; } return l; } void work(int x){ int i; int hh=0,tt=0; q[tt]=node{1,n,1}; for(i=2;i<=n;i++){ while(hh<=tt&&q[hh].r<i) hh++; int p=q[hh].p; f[x][i]=ceil(check(i,p)); int pos=n+1; while(hh<=tt){ int l=q[tt].l,r=q[tt].r; p=q[tt].p; if(l>i){ if(check(l,i)>check(l,p)){ --tt; pos=l; continue; } } if(check(r,i)>check(r,p)) pos=find(i+1,r,i,p); q[tt].r=pos-1; if(pos<=n){ q[++tt]=node{pos,n,i}; } break; } } } int main(){ ios::sync_with_stdio(0); cin>>n; int i; for(i=1;i<=n;i++){ cin>>a[i]; } work(0); reverse(a+1,a+1+n); work(1); int ans=0; for(i=1;i<=n;i++){ ans=max(f[0][i],f[1][n-i+1]); ans=max(ans,0); cout<<ans<<endl; } return 0; }
没有人不辛苦,只有人不喊疼