SPOJ GSS3 线段树

来源:互联网 发布:php 加一个月 编辑:程序博客网 时间:2024/05/20 03:06

题意:在询问一段数列的连续最大自序列和的基础上又增加了单点修改


解法:单点修改还是很简单的吧 其实gss这两题主要是要从线段树的先序遍历进行思考就可以了

如果拓展一下LCIS能不能也这样做呢?我觉得也是可以的 

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 50005#define inf 0x3f3f3f3f#define ls (rt<<1)#define rs (rt<<1|1)#define mid ((l+r)>>1)int lm[maxn<<2],rm[maxn<<2],mm[maxn<<2],sum[maxn<<2];int ans,pre;void up(int rt){    sum[rt]=sum[ls]+sum[rs];    mm[rt]=max(mm[ls],mm[rs]);    lm[rt]=max(lm[ls],sum[ls]+max(0,lm[rs]));    rm[rt]=max(rm[rs],sum[rs]+max(0,rm[ls]));    mm[rt]=max(mm[rt],rm[ls]+lm[rs]);}void build(int rt,int l,int r){    if(l==r){        scanf("%d",&mm[rt]);        sum[rt]=lm[rt]=rm[rt]=mm[rt];        return;    }    build(ls,l,mid);    build(rs,mid+1,r);    up(rt);}void ins(int rt,int l,int r,int L,int R,int w){    if(L<=l&&r<=R){        sum[rt]=mm[rt]=lm[rt]=rm[rt]=w;        return ;    }    if(L<=mid)ins(ls,l,mid,L,R,w);    if(mid<R)ins(rs,mid+1,r,L,R,w);    up(rt);}void query(int rt,int l,int r,int L,int R){    if(L<=l&&r<=R){        ans=max(ans,mm[rt]);        ans=max(ans,pre+lm[rt]);        pre=max(rm[rt],pre+sum[rt]);        return;    }    if(L<=mid)query(ls,l,mid,L,R);    if(mid<R)query(rs,mid+1,r,L,R);}int main(){    int n,m,a,b,op;    while(~scanf("%d",&n)){        build(1,1,n);        scanf("%d",&m);        while(m--){            scanf("%d%d%d",&op,&a,&b);            if(op){              ans=pre=-inf;                query(1,1,n,a,b);                  printf("%d\n",ans);            }else{                ins(1,1,n,a,a,b);            }        }    }    return 0;}


0 0
原创粉丝点击