Test 51T2: Monotone maintain the stack convex hull half

Monotone stack maintenance convex hull, and two points on the convex hull of a class of problems.

1, each decision point this problem is to maintain a linear function, namely a line.

2, the convex hull of maintenance: 1, the slope increment, pop out of the slope is greater than his
                    2, decreasing the intersection, not preferable to prevent influence the decision line

3, write their own code, she did not see std, change does not come out after watching the second while, namely the intersection of diminishing, not taken into account.

This is better. To believe that they can write it down.

See detailed notes.

#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
     / * Maintenance * Here is the convex hull. The second sentence: that the intersection point within the stack monotonically decreasing. Because drawing found the intersection of diminishing became convex hull, or on a line can be removed 
    if not removed, a line decision-making will be used, resulting in block had better decisions 
    to maintain it under the convex hull: 1, the slope of the increment, pop off the slope ratio his big 
              2, the intersection point of diminishing, preventing influence decisions excellent line 
    * / 
    STA [ ++ Top] = X; 
} 
/ * * It can be shown not legal decision point exceeds the boundary not preferable * / 
int Solve ( int X , int Y) {
     int L = . 1 , = R & lt Top, MID;
     the while (L < R & lt) { 
        MID = L + R & lt >> . 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\n",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

 

Guess you like

Origin www.cnblogs.com/seamtn/p/11590161.html
Recommended