zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    在SQLite中使用索引优化查询速度
    SQLite支持的SQL数据操作
    left (outer) join , right (outer) join, full (outer) join, (inner) join, cross join 区别
    深入理解Android内存管理原理(六)
    Merge Sorted Array
    Sort Colors
    Construct Binary Tree from Preorder and Inorder Traversal
    Binary Tree Postorder Traversal
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12791846.html
Copyright © 2011-2022 走看看