zoukankan      html  css  js  c++  java
  • bzoj1500: [NOI2005]维修数列

    splay.

    就是splay,没别的了。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 600000 + 10;
    const int inf = 0x3f3f3f3f;
    
    struct Splay {
        int v[maxn],s[maxn],sum[maxn];
        int l[maxn],r[maxn],f[maxn];
        int maxl[maxn],maxr[maxn],maxs[maxn];
        int same[maxn],rev[maxn];
        int q[maxn+1000],h,t;
        int root;
        
        int newnode() {
            int x=q[h++];
            if(h==maxn) h=0;
            return x;
        }
        
        void recycle(int x) {
            if(x==0) return;
            recycle(l[x]);
            recycle(r[x]);
            q[t++]=x;
            if(t==maxn) t=0;
        }
        
        void reverse(int x) {
            swap(l[x],r[x]);
            swap(maxl[x],maxr[x]);
            rev[x]^=1;    
        }
        
        void make_same(int x,int val) {
            same[x]=v[x]=val;
            sum[x]=s[x]*val; 
            if(val>0) maxl[x]=maxr[x]=maxs[x]=sum[x];
            else {maxl[x]=maxr[x]=0; maxs[x]=val;}
        }
        
        void push(int x) {
            if(same[x]!=inf) {
                make_same(l[x],same[x]);
                make_same(r[x],same[x]);
                same[x]=inf;
                if(rev[x]) rev[x]=0;    
            }
            if(rev[x]) {
                reverse(l[x]);
                reverse(r[x]);
                rev[x]=0;
            }
        }
        
        void update(int x) {    
            sum[x]=sum[l[x]]+sum[r[x]]+v[x];
            maxl[x]=max(maxl[l[x]],sum[l[x]]+v[x]+maxl[r[x]]);
            maxr[x]=max(maxr[r[x]],sum[r[x]]+v[x]+maxr[l[x]]);
            maxs[x]=max(max(maxs[l[x]],maxs[r[x]]),maxr[l[x]]+v[x]+maxl[r[x]]);
            s[x]=s[l[x]]+s[r[x]]+1;
        }
        
        void lr(int x) {
            int y=f[x];
            r[y]=l[x];
            if(l[x]) f[l[x]]=y;
            f[x]=f[y];
            if(root==y) root=x;
            else if(l[f[y]]==y) l[f[y]]=x;
            else r[f[y]]=x;
            f[y]=x; l[x]=y;
            update(y);
            update(x);
        }
        
        void rr(int x) {
            int y=f[x];
            l[y]=r[x];
            if(r[x]) f[r[x]]=y;
            f[x]=f[y];
            if(root==y) root=x;
            else if(l[f[y]]==y) l[f[y]]=x;
            else r[f[y]]=x;
            f[y]=x; r[x]=y;
            update(y);
            update(x);
        }
        
        void rotate(int x) {
            if(l[f[x]]==x) rr(x);
            else lr(x);
        }
        
        void splay(int x,int target=0) {
            while(f[x]!=target) {
                if(f[f[x]]==target) rotate(x);
                else if((l[f[x]]==x)==(l[f[f[x]]]==f[x])) {rotate(f[x]); rotate(x);}
                else {rotate(x); rotate(x);}
            }
        }
        
        int find(int k) {
            int x=root;
            push(x);
            while(k!=s[l[x]]+1) {
                if(k>s[l[x]]+1) {k-=s[l[x]]+1; x=r[x];}
                else x=l[x];
                push(x);
            }    
            return x;
        }
        
        void Insert(int pos,int tot) {
            splay(find(pos+1),0);
            splay(find(pos+2),root);
            build(l[r[root]],r[root],1,tot);
            update(r[root]);
            update(root);    
        }
        
        void Delete(int pos,int tot) {
            splay(find(pos),0);
            splay(find(pos+tot+1),root);
            recycle(l[r[root]]);
            l[r[root]]=0;
            update(r[root]);
            update(root);    
        }
        
        void Make(int pos,int tot,int val) {
            splay(find(pos),0);
            splay(find(pos+tot+1),root);
            make_same(l[r[root]],val);
            update(r[root]);
            update(root);
        }
        
        void Reverse(int pos,int tot) {
            splay(find(pos),0);
            splay(find(pos+tot+1),root);
            reverse(l[r[root]]);
            update(r[root]);
            update(root);
        }
        
        int Get_sum(int pos,int tot) {
            splay(find(pos),0);
            splay(find(pos+tot+1),root);
            return sum[l[r[root]]];
        }
        
        int Max_sum() {
            return maxs[root];
        }
        
        void build(int &x,int fa,int L,int R) {
            if(L>R) {x=0; return;}
            x=newnode(); f[x]=fa; same[x]=inf; rev[x]=0;
            int mid=(L+R)/2;
            build(l[x],x,L,mid-1);
            scanf("%d",&v[x]); 
            build(r[x],x,mid+1,R);
            update(x);
        }
        
        void init(int n) {
            v[0]=v[1]=v[2]=maxs[0]=-inf; 
            same[1]=same[2]=inf;
            r[1]=2; f[2]=1; s[1]=2; s[2]=1;
            root=1;
            update(2); update(1);
            for(int i=3;i<maxn;i++) q[t++]=i;
            
            build(l[r[root]],r[root],1,n);    
            update(r[root]);
            update(root);
        }
        
        /*void debug(int x) {
            if(!x) return;
            //push(x);
            debug(l[x]);
            printf("%d ",v[x]);
            debug(r[x]);
        }*/
    }splay;
    
    char op[20];
    int n,m,val,tot,pos;
    
    int main() {
        scanf("%d%d",&n,&m);
        splay.init(n);
        
        while(m--) {
            //splay.debug(splay.root);
            scanf("%s",op);
            if(op[0]=='I') {
                scanf("%d%d",&pos,&tot);
                splay.Insert(pos,tot);
            }
            else if(op[0]=='D') {
                scanf("%d%d",&pos,&tot);
                splay.Delete(pos,tot);    
            }
            else if(op[0]=='M' && op[2]=='K') {
                scanf("%d%d%d",&pos,&tot,&val);
                splay.Make(pos,tot,val);
            }
            else if(op[0]=='R') {
                scanf("%d%d",&pos,&tot);
                splay.Reverse(pos,tot);    
            }
            else if(op[0]=='G') {
                scanf("%d%d",&pos,&tot);
                printf("%d
    ",splay.Get_sum(pos,tot));
            }
            else {
                printf("%d
    ",splay.Max_sum());
            }
        }    
        return 0;
    }
  • 相关阅读:
    bzoj3505 数三角形 组合计数
    cogs2057 殉国 扩展欧几里得
    cogs333 荒岛野人 扩展欧几里得
    bzoj1123 BLO tarjan求点双连通分量
    poj3352 road construction tarjan求双连通分量
    cogs1804 联合权值 dp
    cogs2478 简单的最近公共祖先 树形dp
    cogs1493 递推关系 矩阵
    cogs2557 天天爱跑步 LCA
    hdu4738 Caocao's Bridge Tarjan求割边
  • 原文地址:https://www.cnblogs.com/invoid/p/5615793.html
Copyright © 2011-2022 走看看