SPOJ 1043

来源:互联网 发布:js按钮取消点击事件 编辑:程序博客网 时间:2024/06/05 14:41

题目链接:  http://www.spoj.pl/problems/GSS1/

———————————————————————————————————————

题目关键字:  线段树

———————————————————————————————————————

question: 为何这样做能够降低复杂度。

———————————————————————————————————————

#include <stdio.h>#include <stdlib.h>struct tree{    int left;    int right;    int val;    int per;    int suf;}tree[500010];int a[50010],sum[50010];int n = 0,m = 0;void init(int cur,int l,int r){    tree[cur].left = l;    tree[cur].right = r;    if(l!=r)    {       tree[cur].val = 0;       init(cur*2,l,(l+r)/2);       init(cur*2+1,(l+r)/2+1,r);    }    else    {       tree[cur].val = a[l];       tree[cur].per = a[l];       tree[cur].suf = a[l];    }}long long max(long long a,long long b,long long c){    if(a>b)    {      if(a>c)        return a;      else return c;    }    else    {      if(b>c)         return b;      else return c;    }}void create(int cur,int l,int r)         //1查总和,2查前缀,3查后缀{    int m = (l+r)>>1;    if(l!=r)    {       create(cur*2,l,m);       create(cur*2+1,m+1,r);       tree[cur].val = max(tree[cur*2].val,tree[cur*2+1].val,tree[cur*2].suf+ tree[cur*2+1].per);       tree[cur].per = max(tree[cur*2].per,tree[cur*2+1].per+ sum[m] - sum[l-1],-9223372036854775808);       tree[cur].suf = max(tree[cur*2+1].suf,sum[r]-sum[m]+ tree[cur*2].suf,-9223372036854775808);    }}struct tree query(int cur,int l,int r)                                 //返回的是一个值{    int m = (tree[cur].left + tree[cur].right)/2;          //值一定要搞清楚    struct tree ans,le,ri;    if(tree[cur].left == l && tree[cur].right == r)       return tree[cur];    if(r<=m) return query(cur*2,l,r);    else if(l>m) return query(cur*2+1,l,r);         else         {             le = query(cur*2,l,m);             ri = query(cur*2+1,m+1,r);             ans.per = max(le.per,sum[le.right]-sum[le.left-1]+ ri.per,-9223372036854775808);             ans.suf = max(ri.suf,sum[ri.right]-sum[ri.left-1]+ le.suf,-9223372036854775808);             ans.val = max(le.suf+ri.per,le.val,ri.val);             return ans;         }}int main(){    int i = 0;    int l = 0,r = 0;    struct tree  ans ;    scanf("%d",&n);    sum[0] = 0;    for(i = 1;i<=n;i++)   {      scanf("%d",&a[i]);      sum[i] = a[i] + sum[i-1];   }    init(1,1,n);    create(1,1,n);    scanf("%d",&m);    for(i = 0;i<m;i++)    {        scanf("%d%d",&l,&r);        ans = query(1,l,r);        printf("%I64d\n",ans.val);    }    return 0;}