SPOJ GSS1 Can you answer these queries I
You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defined as follows:
Query(x,y) = Max { a[i]+a[i+1]+...+a[j] ; x ≤ i ≤ j ≤ y }.
Given M queries, your program must output the results of these queries.
Input
- The first line of the input file contains the integer N.
- In the second line, N numbers follow.
- The third line contains the integer M.
- M lines follow, where line i contains 2 numbers xi and yi.
Output
-
Your program should output the results of the M queries, one query per line.
Example
Input: 3 -1 2 3 1 1 2 Output: 2
对于线段树的一个结点,维护其总区间的最大序列,左起区间的最大序列(la),右起区间的最大序列(ra)。
虽然有一些思路,但是并没有那么好写,尤其是在刷了一天学校的题,大脑基本停转的时候。
改来改去改不对,最后抄了别人的题解。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<list> using namespace std; struct NODE{ int l,r; int max,sum;//最大区间以及整个区间和 int ra,la;//左右字树的和 }e[200000]; int data[200000]; int n,m; void Build(int l,int r,int num){ e[num].l=l; e[num].r=r; if(l==r){ e[num].sum=data[l]; e[num].max=data[l]; e[num].ra=e[num].la=data[l]; return; } int mid=(l+r)/2; Build(l,mid,num<<1); Build(mid+1,r,num*2+1); e[num].sum=e[num<<1].sum+e[num*2+1].sum; e[num].la=max(e[num<<1].la,e[num<<1].sum+e[num<<1].la); e[num].ra=max(e[num<<1].ra,e[num<<1].sum+e[num<<1].ra); e[num].max=max(e[num<<1].ra+e[num*2+1].la,max(e[num<<1].max,e[num*2+1].max)); return; } NODE qu(int l,int r,int num){ NODE node,n1,n2; if(e[num].r<=r && e[num].l>=l)return e[num]; int mid=(e[num].l+e[num].r)/2; if(mid<l){ n2=qu(l,r,num*2+1); return n2; }else if(mid>=r){ n1=qu(l,r,num*2); return n1; } n1=qu(l,r,num*2);n2=qu(l,r,num*2+1); node.sum=n1.sum+n2.sum; node.la=max(n1.la,n1.sum+n2.la); node.ra=max(n2.ra,n2.sum+n1.ra); node.max=max(n1.ra+n2.la,max(n1.max,n2.max)); return node; } int main(){ scanf("%d",&n); int i,j; for(i=1;i<=n;i++)scanf("%d",&data[i]); Build(1,n,1); scanf("%d",&m); int x,y; for(i=1;i<=m;i++){ scanf("%d%d",&x,&y); NODE a=qu(x,y,1); printf("%d\n",a.max); } return 0; }
本文为博主原创文章,转载请注明出处。