【BZOJ1500】【Noi2005】维修数列

题意原题很清楚了。

解题思路:裸的平衡树操作,注意动态开点即可。

细节还是比较多的,具体参见代码吧。。。

#include <stdio.h>
#include <algorithm>
#define r register
#define max(a,b) ((a)>(b)?(a):(b))
inline int in(){
    r int x=0;r bool f=0;r char c;
    for (;(c=getchar())<'0'||c>'9';) f=c=='-';
    for (x=c-'0';(c=getchar())>='0'&&c<='9';) x=(x<<3)+(x<<1)+c-'0'; 
    return f?-x:x;
}
namespace Treap{
    inline int Rand(){
        static int x=23333;
        return x^=x<<13,x^=x>>17,x^=x<<5;
    }
    struct node{
        node *ls,*rs; bool rev,sam;
        int val,sz,pri,sum,lx,rx,mx;
        node(int x):val(x),sz(1),pri(Rand()){sum=mx=lx=rx=val,rev=sam=0,ls=rs=NULL;}
        inline void reverse(){
            std::swap(ls,rs);  
            if(ls) ls->rev^=1,std::swap(ls->lx,ls->rx);  
            if(rs) rs->rev^=1,std::swap(rs->lx,rs->rx);  
        }
        inline void combine(){
            sum=mx=lx=rx=val;  
            sz=1;  
            if(ls) sum+=ls->sum,sz+=ls->sz;  
            if(rs) sum+=rs->sum,sz+=rs->sz;  
            if(ls){  
                lx=ls->lx;  
                lx=max(lx,ls->sum+val);  
                if(rs) lx=max(lx,ls->sum+val+rs->lx);  
            }else if(rs) lx=max(lx,val+rs->lx);        
            if(rs){  
                rx=rs->rx;  
                rx=max(rx,rs->sum+val);  
                if(ls) rx=max(rx,rs->sum+val+ls->rx);  
            }else if(ls) rx=max(rx,val+ls->rx);
            if(ls){  
                mx=max(mx,ls->mx);  
                mx=max(mx,ls->rx+val);  
            }  
            if(rs){  
                mx=max(mx,rs->mx);  
                mx=max(mx,rs->lx+val);  
            }  
            if(ls&&rs) mx=max(mx,ls->rx+val+rs->lx);  
        }
        inline void pushdown(){
            if (sam){
                if (ls){
                    ls->val=val;
                    ls->sum=ls->sz*val;
                    ls->sam=1;
                    if (val>0) ls->mx=ls->lx=ls->rx=ls->sum;
                    else ls->mx=ls->lx=ls->rx=val;
                }
                if (rs){
                    rs->val=val;
                    rs->sum=rs->sz*val;
                    rs->sam=1;
                    if (val>0) rs->mx=rs->lx=rs->rx=rs->sum;
                    else rs->mx=rs->lx=rs->rx=val;
                }sam=0;
            }
            if (rev) reverse(),rev=0;
        }
    }*root;
    struct Droot{node *a,*b;};
    inline int Size(node *x){return x?x->sz:0;}
    node *merge(node *a,node *b){
        if (!a) return b;
        if (!b) return a;
        if (a->pri<b->pri){
            a->pushdown();
            a->rs=merge(a->rs,b);
            a->combine();
            return a;
        }else{
            b->pushdown();
            b->ls=merge(a,b->ls);
            b->combine();
            return b;
        }
    }
    Droot split(node *x,int k){
        if (!x) return (Droot){NULL,NULL}; 
        r Droot y; x->pushdown();
        if (Size(x->ls)>=k){
            y=split(x->ls,k);
            x->ls=y.b;
            x->combine();
            y.b=x;
        }else{
            y=split(x->rs,k-Size(x->ls)-1);
            x->rs=y.a;x->combine();y.a=x;
        }return y;
    }
    inline void trash(node *&x){
        if (!x) return;
        trash(x->ls),trash(x->rs);
        delete x;x=NULL;
    }
    inline int Get_Sum(int s,int l){
        if (l==0) return 0;
        r Droot x=split(root,s-1);
        r Droot y=split(x.b,l);
        r int ans=y.a->sum;
        root=merge(merge(x.a,y.a),y.b);
        return ans;
    }
    inline int Get_Max(){return root?root->mx:0;}
    inline void Delete(int s,int l){
        r Droot x=split(root,s-1);
        r Droot y=split(x.b,l);
        root=merge(x.a,y.b);trash(y.a);
    }
    inline void Make_Same(int s,int l,int val){
        r Droot x=split(root,s-1);
        r Droot y=split(x.b,l);
        y.a->val=val;y.a->sam=1;y.a->rev=0,y.a->sum=y.a->sz*val;
        if (val>0) y.a->mx=y.a->lx=y.a->rx=y.a->sum;
        else y.a->mx=y.a->lx=y.a->rx=val;
        root=merge(merge(x.a,y.a),y.b);
    }
    inline void Reverse(int s,int l){
        r Droot x=split(root,s-1);
        r Droot y=split(x.b,l);
        y.a->rev=1; std::swap(y.a->lx,y.a->rx);
        root=merge(merge(x.a,y.a),y.b);
    }
    inline node *insert(int k){
        if (!k) return NULL;
        if (k==1){
            r node *ans=new node(in());
            return ans;
        }
        r node *a,*b;
        a=insert(k>>1);
        b=insert(k-(k>>1));
        return merge(a,b);
    }
    inline void Insert(){
        r int pos=in(),n=in();
        r node *ans=insert(n);
        r Droot x=split(root,pos);
        root=merge(merge(x.a,ans),x.b);
    }
}using namespace Treap;int n,q;
void init(){n=in(),q=in();root=insert(n);}
void solve(){
    while(q--){
        r char op[20];scanf("%s",op);
        if (op[0]=='M'){
            if (op[2]=='K'){
                r int x=in(),n=in();
                Make_Same(x,n,in());
            }else printf("%d\n",Get_Max());
        }
        else{
            switch(op[0]){
                case 'I':Insert();break;
                case 'D':{r int x=in();Delete(x,in());break;}
                case 'R':{r int x=in();Reverse(x,in());break;}
                case 'G':{r int x=in();printf("%d\n",Get_Sum(x,in()));break;}
            }
        }
    }
}
int main(){init(); solve(); return 0;}

 

posted @ 2017-05-08 17:20  Melacau  阅读(191)  评论(0编辑  收藏  举报