[SPOJ1716] GSS3 - Can you answer these queries III

线段树操作。
维护一个区间最大连续子段和,左最大连续子段和,右最大连续子段和即可。
最后不知道怎么搞,query的时候返回了个结构体。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N=50005;
int n,q,a[N],opt,x,y;
struct Segtree{int l,r,lmx,rmx,mx,sum;}t[N<<3];
void pushup(int cur){
    t[cur].sum=t[cur<<1].sum+t[cur<<1|1].sum;
    t[cur].lmx=max(t[cur<<1].sum+t[cur<<1|1].lmx,t[cur<<1].lmx);
    t[cur].rmx=max(t[cur<<1|1].sum+t[cur<<1].rmx,t[cur<<1|1].rmx);
    t[cur].mx=max(t[cur<<1].mx,max(t[cur<<1|1].mx,t[cur<<1].rmx+t[cur<<1|1].lmx));
}
void build(int cur,int l,int r){
    t[cur].l=l,t[cur].r=r;
    if(l==r) {t[cur].sum=t[cur].rmx=t[cur].lmx=t[cur].mx=a[l];return;}
    int mid=l+r>>1;
    build(cur<<1,l,mid);
    build(cur<<1|1,mid+1,r);
    pushup(cur);
}
void update(int cur,int c,int now) {
    if(t[cur].l==t[cur].r) {t[cur].sum=t[cur].lmx=t[cur].rmx=t[cur].mx=c;return;}
    int mid=t[cur].l+t[cur].r>>1;
    if(now<=mid) update(cur<<1,c,now);
    else update(cur<<1|1,c,now);
    pushup(cur);
}
Segtree query(int l,int r,int cur) {
    if(l<=t[cur].l&&t[cur].r<=r) return t[cur];
    int mid=t[cur].l+t[cur].r>>1;
    if(l>mid) return query(l,r,cur<<1|1);
    if(r<=mid) return query(l,r,cur<<1);
    Segtree x=query(l,r,cur<<1),y=query(l,r,cur<<1|1),ans;
    ans.mx=max(x.mx,max(y.mx,x.rmx+y.lmx));
    ans.lmx=max(x.lmx,x.sum+y.lmx);
    ans.rmx=max(x.rmx+y.sum,y.rmx);
    return ans;
}
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    scanf("%d",&q);
    build(1,1,n);
    while(q--) {
        scanf("%d%d%d",&opt,&x,&y);
        if(opt) printf("%d\n",query(x,y,1).mx);
        else update(1,y,x);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sdfzhsz/p/9296316.html