Every dish has its own value represented by an integer whose absolute value is less than 1,000,000,000. Before having dinner, Neal is wondering about the total value of the dishes he will eat. So he raises many questions about the values of dishes he would have.
For each question Neal asks, he will first write down an interval [a, b] (inclusive) to represent all the dishes a, a + 1,..., b , where a and b are positive integers, and then asks Ray which sequence of consecutive dishes in the interval has the most total value. Now Ray needs your help.
Input
The input file contains multiple test cases. For each test case, there are two integers n and m in the first line (n, m < 500000) . n is the number of dishes and m is the number of questions Neal asks.
Then n numbers come in the second line, which are the values of the dishes from left to right. Next m lines are the questions and each line contains two numbers a , b as described above. Proceed to the end of the input file.
Output
For each test case, output m lines. Each line contains two numbers, indicating the beginning position and end position of the sequence. If there are multiple solutions, output the one with the smallest beginning position. If there are still multiple solutions then, just output the one with the smallest end position. Please output the result as in the Sample Output.
Sample Input
3 1 1 2 3 1 1
Sample Output
Case 1: 1 1
题目如上
思路书讲得比较清楚,但实现有些麻烦,思路见码
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> using namespace std; #define LL long long const int maxn=500000+10; int a[maxn],ql,qr; struct node{ LL pre,sux,maxsum,sum; int l,r,prer,suxl; }e[2*maxn]; void build(int o,int L,int R){ if(L==R){ e[o].pre=e[o].sux=e[o].maxsum=e[o].sum=a[L]; e[o].l=e[o].r=e[o].prer=e[o].suxl=L; return; } int M=L+(R-L)/2; build(2*o,L,M); build(2*o+1,M+1,R); e[o].sum=e[2*o].sum+e[2*o+1].sum; if(e[2*o].pre>=e[2*o].sum+e[2*o+1].pre){ e[o].pre=e[2*o].pre; e[o].prer=e[2*o].prer; } else{ e[o].pre=e[2*o].sum+e[2*o+1].pre; e[o].prer=e[2*o+1].prer; } if(e[2*o+1].sux>e[2*o].sux+e[2*o+1].sum){ e[o].sux=e[2*o+1].sux; e[o].suxl=e[2*o+1].suxl; } else{ e[o].sux=e[2*o].sux+e[2*o+1].sum; e[o].suxl=e[2*o].suxl; } LL aa=e[2*o].maxsum,cc=e[2*o+1].maxsum,bb=e[2*o].sux+e[2*o+1].pre; if(cc>bb&&cc>aa){ e[o].maxsum=cc; e[o].l=e[2*o+1].l,e[o].r=e[2*o+1].r; } else if(bb>aa){ e[o].maxsum=bb; e[o].l=e[2*o].suxl,e[o].r=e[2*o+1].prer; } else{ e[o].maxsum=aa; e[o].l=e[2*o].l,e[o].r=e[2*o].r; } } node query(int o,int L,int R){ int M=L+(R-L)/2; if(ql<=L&&qr>=R) return e[o]; if(ql>M) return query(2*o+1,M+1,R); if(qr<=M) return query(2*o,L,M); else{ node p=query(2*o,L,M),q=query(2*o+1,M+1,R),n; n.sum=p.sum+q.sum; if(p.pre>=p.sum+q.pre){ n.pre=p.pre; n.prer=p.prer; } else{ n.pre=p.sum+q.pre; n.prer=q.prer; } if(q.sux>p.sux+q.sum){ n.sux=q.sux; n.suxl=q.suxl; } else{ n.sux=p.sux+q.sum; n.suxl=p.suxl; } LL aa=p.maxsum,cc=q.maxsum,bb=p.sux+q.pre; if(cc>bb&&cc>aa){ n.maxsum=cc; n.l=q.l,n.r=q.r; } else if(bb>aa){ n.maxsum=bb; n.l=p.suxl,n.r=q.prer; } else{ n.maxsum=aa; n.l=p.l,n.r=p.r; } return n; } } int main() { int n,m,tt=0;; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,1,n); node ans; printf("Case %d:\n",++tt); for(int i=0;i<m;i++) { scanf("%d%d",&ql,&qr); ans=query(1,1,n); printf("%d %d\n",ans.l,ans.r); } } return 0; }