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 */