zoukankan      html  css  js  c++  java
  • 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(' '); 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(' '); else read(q1),read(q2),read(q3),modify(q1,q2,q3); } }return 0; }
  • 相关阅读:
    POJ 2723 Get Luffy Out(2-SAT)
    ZOJ 3613 Wormhole Transport
    HDU 4085 Peach Blossom Spring
    NBUT 1221 Intermediary
    NBUT 1223 Friends number
    NBUT 1220 SPY
    NBUT 1218 You are my brother
    PAT 1131. Subway Map (30)
    ZSTU OJ 4273 玩具
    ZSTU OJ 4272 最佳淘汰算法
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9720887.html
Copyright © 2011-2022 走看看