• 【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
    ",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
    ",Get_Sum(x,in()));break;}
                }
            }
        }
    }
    int main(){init(); solve(); return 0;}
  • 相关阅读:
    MyEclipse 2016CI破解版for Mac
    关于Mac系统中my sql 和navicat for mysql 的连接问题。
    二分总结
    递推总结
    区间DP学习笔记 6/20
    搜索考试
    模板整理
    防线 2020/3/31
    JS 循环遍历JSON数据
    pm am 12小时格式化
  • 原文地址:https://www.cnblogs.com/Melacau/p/6826063.html
Copyright © 2020-2023  润新知