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;
}
View Code

 

posted @ 2020-04-28 09:07  朝暮不思  阅读(165)  评论(0编辑  收藏  举报