P2042 [NOI2005]维护数列

P2042 [NOI2005]维护数列

splay

毒瘤模板splay

自行体会

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue> 
#define re register
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
template <typename T> inline void read(T &x){
    char c=getchar(); x=0; bool f=1;
    while(!isdigit(c)) f= !f||c=='-' ? 0:1,c=getchar();
    while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
    x= f ? x:-x;
}
template <typename T> inline void output(T x){
    if(!x) {putchar(48); return ;}
    if(x<0) putchar('-'),x=-x;
    int wt[50],l=0;
    while(x) wt[++l]=x%10,x/=10;
    while(l) putchar(wt[l--]+48);
}
struct data{
    int fa,ch[2],v,sz,sum,lx,rx,mx,tag,rev;
    void clear(){fa=ch[0]=ch[1]=v=sz=sum=lx=rx=mx=tag=rev=0;}
}a[500005];
int n,m,u,rt,val[500005];
queue <int> lit;
inline void pdn(int o){
    int lc=a[o].ch[0],rc=a[o].ch[1];
    if(a[o].tag){
        a[o].tag=a[o].rev=0;
        a[lc].tag=a[rc].tag=1;
        a[lc].v=a[rc].v=a[o].v;
        a[lc].sum=a[lc].sz*a[o].v;
        a[rc].sum=a[rc].sz*a[o].v;
        if(a[o].v>=0){
            a[lc].lx=a[lc].rx=a[lc].mx=a[lc].sum;
            a[rc].lx=a[rc].rx=a[rc].mx=a[rc].sum;
        }else{
            a[lc].lx=a[lc].rx=0; a[lc].mx=a[lc].v;
            a[rc].lx=a[rc].rx=0; a[rc].mx=a[rc].v;
        }
    /*    a[lc].mx=max(a[o].v,a[lc].sum);
        a[rc].mx=max(a[o].v,a[rc].sum);
        a[lc].lx=a[lc].rx=max(0,a[lc].sum);
        a[rc].lx=a[rc].rx=max(0,a[rc].sum);*/ //注意不等价!(然鹅并不知道为啥QAQ)
    }if(!a[o].rev) return;
    a[o].rev=0; a[lc].rev^=1; a[rc].rev^=1;
    swap(a[lc].ch[0],a[lc].ch[1]);
    swap(a[rc].ch[0],a[rc].ch[1]);
    swap(a[lc].lx,a[lc].rx);
    swap(a[rc].lx,a[rc].rx);
}
inline void mtn(int o){
    if(!o) return;
    int lc=a[o].ch[0],rc=a[o].ch[1];
    a[o].sz=a[lc].sz+a[rc].sz+1;
    a[o].sum=a[lc].sum+a[rc].sum+a[o].v;
    a[o].mx=max(a[lc].rx+a[o].v+a[rc].lx,max(a[lc].mx,a[rc].mx));
    a[o].lx=max(a[lc].lx,a[lc].sum+a[o].v+a[rc].lx);
    a[o].rx=max(a[rc].rx,a[lc].rx+a[o].v+a[rc].sum);
}
inline void rte(int x,int &k){
    int y=a[x].fa,z=a[y].fa;
    int l=(a[y].ch[1]==x),r=l^1;
    if(y==k) k=x;
    else a[z].ch[a[z].ch[1]==y]=x;
    a[a[x].ch[r]].fa=y,a[y].fa=x,a[x].fa=z;
    a[y].ch[l]=a[x].ch[r],a[x].ch[r]=y;
    mtn(y); mtn(x);
}
inline void splay(int x,int &k){
    for(;x!=k;rte(x,k)){
        int y=a[x].fa,z=a[y].fa;
        if(y!=k){
            if((a[y].ch[0]==x)^(a[z].ch[0]==y)) rte(x,k);
            else rte(y,k);
        }
    }
}
inline int find(int x,int k){
    pdn(x);
    int lc=a[x].ch[0],rc=a[x].ch[1];
    if(a[lc].sz+1==k) return x;
    if(a[lc].sz>=k) return find(lc,k);
    else return find(rc,k-a[lc].sz-1);
}
inline int split(int x,int k){
    int l=find(rt,x),r=find(rt,x+1+k);
    splay(l,rt); splay(r,a[l].ch[1]);
    return a[r].ch[0];
}
//-----↑splay核心↑------ inline
void build(int &o,int l,int r,int _fa){ //建树 if(l>r) return; if(!o){ if(!lit.empty()) o=lit.front(),lit.pop(); else o=++u; }int mid=l+((r-l)>>1); a[o].sz=1; a[o].fa=_fa; a[o].tag=a[o].rev=0; a[o].sum=a[o].v=a[o].mx=val[mid]; a[o].lx=a[o].rx=max(0,a[o].v); build(a[o].ch[0],l,mid-1,o); build(a[o].ch[1],mid+1,r,o); mtn(o); } inline void ins(int x,int k){ //插入 for(re int i=1;i<=k;++i) read(val[i]); split(x+1,0); int _rt=0,y=a[rt].ch[1]; build(_rt,1,k,y); a[y].ch[0]=_rt; mtn(y); mtn(rt); } inline void reuse(int x){ if(!x) return; reuse(a[x].ch[0]); reuse(a[x].ch[1]); a[x].clear(); lit.push(x); } inline void remov(int x,int k){ //删除 int _rt=split(x,k); int y=a[rt].ch[1]; reuse(_rt); a[y].ch[0]=0; mtn(y); mtn(rt); } inline void modify(int x,int k,int v){ //修改 int _rt=split(x,k); a[_rt].tag=1,a[_rt].v=v; a[_rt].sum=a[_rt].sz*v; a[_rt].lx=a[_rt].rx=max(0,a[_rt].sum); a[_rt].mx=max(v,a[_rt].sum); mtn(a[_rt].fa); mtn(rt); } inline void reverse(int x,int k){ //旋转 int _rt=split(x,k); if(a[_rt].tag) return; a[_rt].rev^=1; swap(a[_rt].ch[0],a[_rt].ch[1]); swap(a[_rt].lx,a[_rt].rx); mtn(a[_rt].fa); mtn(rt); } inline int query(int x,int k){ int _rt=split(x,k); return a[_rt].sum; } int main(){ read(n); read(m); int q1,q2,q3; char opt[14]; val[1]=val[n+2]=-2e9; for(re int i=2;i<=n+1;++i) read(val[i]); build(rt,1,n+2,0); for(re int i=1;i<=m;++i){ scanf("%s",opt); if(opt[0]=='G') read(q1),read(q2),output(query(q1,q2)),putchar('\n'); else if(opt[0]=='I') read(q1),read(q2),ins(q1,q2); else if(opt[0]=='D') read(q1),read(q2),remov(q1,q2); else if(opt[0]=='R') read(q1),read(q2),reverse(q1,q2); else{ if(opt[2]=='X') output(a[rt].mx),putchar('\n'); else read(q1),read(q2),read(q3),modify(q1,q2,q3); } }return 0; }

 

posted @ 2018-09-28 21:03  kafuuchino  阅读(186)  评论(0编辑  收藏  举报