• 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;
    }
  • 相关阅读:
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    composer安装以及更新问题,配置中国镜像源。
    PHP使用文件排它锁,应对小型并发
  • 原文地址:https://www.cnblogs.com/invoid/p/5615793.html
Copyright © 2020-2023  润新知