7GOJ 24 girls [可持久化Treap--区间操作]

SPOJ–GSS系列的某一道题。。不懂。。就是一个区间翻转,最大连续子段和而已,强上treapAC。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<iostream>
using namespace std;
#define LL long long
const int N=201000;
int n,m,l,r;
char cmd[10];
inline void read(int &res){
    static char ch;int flag=1;
    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
namespace TREAP{
    struct Treap{
        int rd,size,key;
        LL lmax,rmax,ret,sum;
        bool rev;
        Treap *ch[2];
        inline void setting(int v){
            key=sum=v;
            if(v<0)v=0;
            lmax=rmax=ret=v;
        }
        inline void update(){
            rev^=1;
            swap(lmax,rmax);
        }
        inline void pushdown(){
            if(rev){
                swap(ch[0], ch[1]);
                ch[0]->update();
                ch[1]->update();
                rev=0;
            }
        }
        inline void pushup(){
            size=ch[0]->size+ch[1]->size+1;
            lmax=max(ch[0]->lmax,ch[0]->sum+key+ch[1]->lmax);
            rmax=max(ch[1]->rmax,ch[1]->sum+key+ch[0]->rmax);
            sum=ch[0]->sum+key+ch[1]->sum;
            ret=max(ch[0]->ret,ch[1]->ret);
            ret=max(ret,ch[0]->rmax+key+ch[1]->lmax);
        }
        Treap();
    }tail,tree[N];
    Treap *nul=&tail;
    Treap *root=nul;
    Treap::Treap(){
        rd=rand();
        ch[0]=ch[1]=nul; 
        if(this==nul)size=0;
        else size=1;
    }
    Treap *merge(Treap *l,Treap *r){
        if(l==nul)return r;
        if(r==nul)return l;
        if(l->rd>r->rd){
            l->pushdown();
            l->ch[1]=merge(l->ch[1],r);
            l->pushup();
            return l;
        }else{
            r->pushdown();
            r->ch[0]=merge(l,r->ch[0]);
            r->pushup();
            return r;
        }
    }
    inline void split(Treap *rt,int rank,Treap* &l,Treap* &r) {
        rt->pushdown();
        if(!rank){
            l=nul;
            r=rt;
            return;
        }
        Treap *L,*R;
        if(rt->ch[0]->size>=rank){
            split(rt->ch[0],rank,L,R);
            rt->ch[0]=R;l=L;r=rt;
        }else{
            split(rt->ch[1],rank-1-rt->ch[0]->size,L,R);
            rt->ch[1]=L;l=rt;r=R;
        }
        rt->pushup();
    }
    inline void reverse(int l,int r){
        Treap *L,*mid,*R;
        split(root,l-1,L,mid);
        split(mid,r-l+1,mid,R);
        mid->update();
        mid=merge(L,mid);
        root=merge(mid,R);
    }
    inline void modify(int id,int v){
        Treap *L,*mid,*R;
        split(root,id-1,L,mid);
        split(mid,1,mid,R);
        mid->setting(v);
        mid=merge(L,mid);
        root=merge(mid,R);
    }
    inline void init(){
        for(register int tmp,i=1;i<=n;i++){
            read(tmp),tree[i].setting(tmp);
            root=merge(root,&tree[i]);
        }
    }
    inline LL query(int l,int r){
        Treap *L,*mid,*R;
        split(root,l-1,L,mid);
        split(mid,r-l+1,mid,R);
        LL ans=mid->ret;
        mid=merge(L,mid);
        root=merge(mid,R);
        return ans;
    }
}
using namespace TREAP;
int main(){
    srand((unsigned)time(NULL));
    read(n),read(m);
    init();
    while(m--){
        scanf("%s",cmd),read(l),read(r);
        if(cmd[0]=='Q')cout<<query(l,r)<<endl;
        else if(cmd[0]=='R')reverse(l,r);
        else modify(l, r);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值