zoukankan      html  css  js  c++  java
  • 测试51T2:单调栈维护下凸包二分

    单调栈维护凸包,并在凸包上二分的一类题。

    1、本题维护的每个决策点是一个一次函数,即一条线。

    2、下凸包的维护:1、斜率递增,pop掉斜率比他大的
                        2、交点递减,防止不优的线影响决策

    3、代码自己写的,开始没看std,改不出来后看了第二个while,即交点递减,没考虑到。

    这点比较好。要相信自己也能写出来。

    详细见注释。

    #include<bits/stdc++.h>
    #define F(i,a,b) for(rg int i=a;i<=b;++i)
    #define rg register
    #define LL long long
    #define il inline
    #define pf(a) printf("%lld ",a)
    #define phn puts("")
    using namespace std;
    #define int LL 
    #define N 500010
    int read();
    int n,que;
    int s[N],a[N],c[N];
    int min(int x,int y){return x<y?x:y;}
    int max(int x,int y){return x>y?x:y;}
    struct Q{
        int x,y,id;
        friend bool operator <(const Q& a,const Q& b){return a.y<b.y||(a.y==b.y&&a.x<b.x);}
    }b[N];
    int sta[N],top,ans[N];
    double get(int i,int j){
        return 1.0*(c[j]-c[i])/(a[i]-a[j]);
    }
    void push(int x){
        while(top&&a[sta[top]]>=a[x])--top;
        while(top>1&&get(x,sta[top])>=get(sta[top],sta[top-1]))--top;
        /** 这里是凸包的维护。第二句:使交点在栈内单调递减。因为画图发现交点递减才成为凸包,否则上一条线可以去掉
        如果不去掉,决策会使用上一条线,导致挡住原本更优的决策
        所以下凸包的维护:1、斜率递增,pop掉斜率比他大的
                  2、交点递减,防止不优的线影响决策
        */
        sta[++top]=x;
    }
    /** 可以证明,超过边界的不合法的决策点不优*/
    int solve(int x,int y){
        int l=1,r=top,mid;
        while(l<r){
            mid=l+r>>1;
        //    if(y-sta[mid]+1>x){l=mid+1;continue;}
            if(get(sta[mid],sta[mid+1])>x-y)l=mid+1;
            else r=mid;
        }    
        l=sta[l];
    //    pf(l);pf(x);pf(y);phn;
        /*if(x==100&&y==7){
            F(i,1,top)pf(a[sta[i]]);phn;while(1);
        }*/
        return s[y]-s[l]+(x-y+l)*a[l];
    }
    signed main(){
    //    freopen("function2.in","r",stdin);    freopen("1.out","w",stdout);
        n=read(); F(i,1,n)s[i]=s[i-1]+(a[i]=read()),c[i]=i*a[i]-s[i];
        que=read(); F(i,1,que)b[i]=(Q){read(),read(),i};
        sort(b+1,b+que+1);
        int p=1;
        while(b[p].y==1){
            ans[b[p].id]=a[1]*b[p].x;++p;
        }    
        sta[top=1]=1;
        /**     s[y]0-s[i]+(x-y+i)*a[i] 
            先判两个端点。
        */
        int i,x,y;
        F(k,2,n){    
            push(k);
            if(top==1){
                i=sta[1];
                while(b[p].y==k){
                    ans[b[p].id]=a[k]*b[p].x;
                    ++p;
                }
                continue;
            }
            while(b[p].y==k){
                ans[b[p].id]=solve(b[p].x,k);
                ++p;
            }
        //    push(k);
        }    
        F(i,1,que)printf("%lld
    ",ans[i]);
    }
    int read(){
        int s=0,f=0;char ch;
        while(ch=getchar(),ch=='-'?f=1:0,!isdigit(ch));
        for(;isdigit(ch);s=s*10+(ch^48),ch=getchar());
        return f?-s:s;
    }
    /*
    g++ 1.cpp -g
    ./a.out
    g++ dp.cpp -g
    ./a.out
    10
    10 9 1 7 4 6 8 5 2 3
    10
    4 2
    100 2
    6 3
    1 4
    3 5
    1 7
    100 7 
    5 8
    2 9
    100 10
    */
    View Code

     关于不合法的点一定不优的证明:

    我证出来了,但是懒得写了。我要去看T3了。

  • 相关阅读:
    I方法怎么不能获取多选框的数据
    html checkbox多选框语法与结构
    你真的了解new function(){} 和 function(){}()吗?
    适配方案(六)适配的基础知识之页面中那些内容需要适配
    适配方案(五)适配的基础知识之设备像素比 dpr 与 1px 物理像素
    适配方案(四)适配的基础知识之单位、分辨率、viewport
    onreadystatechange和onload区别分析以及如何判断script是否加载状态
    WebFont技术使用之如何在app中使用自定义字体
    服务端相关知识学习(六)Zookeeper client
    服务端相关知识学习(五)之Zookeeper leader选举
  • 原文地址:https://www.cnblogs.com/seamtn/p/11590161.html
Copyright © 2011-2022 走看看