spojGSS1 线段树维护区间和最大值

http://www.spoj.com/problems/GSS1/
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

题意:

给定长度为N的数串,M个询问插叙[a,b]的的最大连续子段和;

tip:

线段树维护左端最大、右端最大、全局最大和整体和
询问的时候比较所有独立区间最大值,以及不同区间连接起来的最值

#include 
#include 
#include 
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 50010;
using namespace std;
int n,m;
struct node{
    int sum;
    int maxin;
    int lmax,rmax;
}tree[4*maxn];

void build(int l,int r,int rt){
    if(l == r){
        int a;
        scanf("%d",&a);
        tree[rt].sum = tree[rt].maxin = tree[rt].lmax = tree[rt].rmax = a;
        //printf("tree[%d].maxin = %d\n",rt,tree[rt].maxin);
        return;
    }
    int m = (l+r)>>1;
    build(lson);
    build(rson);
    tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
    //printf("tree[%d] .maxin = max(tree[%d].maxin = %d ,tree[%d].maxin",rt,rt << 1,tree[rt << 1].maxin,rt << 1|1,tree[rt << 1|1].maxin);
    tree[rt].maxin = max(max(tree[rt << 1].maxin,tree[rt << 1|1].maxin),tree[rt << 1].rmax+tree[rt << 1|1].lmax);
    tree[rt].lmax = max(tree[rt << 1].lmax,tree[rt << 1].sum+tree[rt<<1|1].lmax);
    tree[rt].rmax = max(tree[rt << 1|1].rmax,tree[rt << 1|1].sum+tree[rt << 1].rmax);
}
int ret,ans,ll,rr;//ret means connecting with other interval

void qurry(int ql,int qr,int l,int r,int rt){
    if(ql <= l && qr >= r){
        //printf("l = %d r = %d  rt = %d\n",l,r,rt);
        ans = max(ans,tree[rt].maxin);
        if(ql == l){
            ret = tree[rt].rmax;
        }
        else if(qr == r){
            ret += tree[rt].lmax;
            ans = max(ans,ret);
        }
        else{
            ans = max(ans,ret + tree[rt].lmax);
            if(ret+tree[rt].sum > tree[rt].rmax){
                ret += tree[rt].sum;
                ans = max(ans,ret);
            }
            else{
                ret = tree[rt].rmax;
                ans = max(ans,ret);
            }

        }
        return;
    }
    int m = (l+r)>>1;
    if(ql <= m) qurry(ql,qr,lson);
    if(qr > m)  qurry(ql,qr,rson);
}

void init(){
    scanf("%d",&n);
    build(1,n,1);
    scanf("%d",&m);
    for(int i = 1; i <= m ; i++){
        ret = 0;
        ans = -(1<<30);
        scanf("%d%d",&ll,&rr);
        qurry(ll,rr,1,n,1);
        printf("%d\n",ans);
    }
}

int main(){
    init();
}

你可能感兴趣的:(acm,基本算法)