• 洛谷P2042 [NOI2005]维护数列


    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<stack>
    #define Tp Treap*
    #define DTp pair<Tp,Tp>
    #define ft first
    #define sc second
    #define INF 0x7f7f7f7f
    #define MAXN 500000+10
    using namespace std;
    int n,m;
    int a[MAXN];
    struct Treap{
        Tp l;Tp r;
        int key,fix;
        int size,sum,lx,rx,mx,tag;
    };
    Tp root;
    stack<Tp> s;
    Tp new_node(int v){
        Tp ret;
        if(s.empty())ret=new Treap;
        else ret=s.top(),s.pop();
        ret->l=ret->r=NULL;
        ret->key=ret->sum=v;
        ret->lx=ret->rx=ret->mx=v;
        ret->tag=-INF;
        ret->size=1,ret->fix=rand();
        return ret;
    }
    int Size(Tp A){return (A?A->size:0);}
    int Sum(Tp A){return (A?A->sum:0);}
    int Lx(Tp A){return (A?A->lx:-INF);}
    int Rx(Tp A){return (A?A->rx:-INF);}
    int Mx(Tp A){return (A?A->mx:-INF);}
    void upd(Tp A){
        A->size=Size(A->l)+Size(A->r)+1;
        A->sum=Sum(A->l)+Sum(A->r)+A->key;
        A->mx=max(max(Mx(A->l),Mx(A->r)),A->key+max(Rx(A->l),0)+max(Lx(A->r),0));
        A->lx=max(Lx(A->l),Sum(A->l)+A->key+max(Lx(A->r),0));
        A->rx=max(Rx(A->r),Sum(A->r)+A->key+max(Rx(A->l),0));
    }
    void Print(Tp A){
        if(!A)return;
     //  pushdown(A); 
     //   printf("key=%d,size=%d,sum=%d,lx=%d,rx=%d,mx=%d
    ",A->key,A->size,A->sum,A->lx,A->rx,A->mx);
        Print(A->l);
        printf("%d ",A->key);
        Print(A->r);
        if(A==root)printf("
    ");    
    }
    void update(Tp A,int x){
        if(!A||-INF==x)return;
        if(x!=INF){
            A->tag=x;
            A->key=x;
            A->sum=x*A->size;
            A->mx=A->lx=A->rx=(x>0?A->sum:x);
        }
        else{
            if(A->tag!=INF&&A->tag!=-INF)return;
            swap(A->l,A->r);
            swap(A->lx,A->rx);
            A->tag=-A->tag;
        }
    }
    void pushdown(Tp A){
        update(A->l,A->tag);
        update(A->r,A->tag);
        A->tag=-INF;
    }
    Tp build(int L,int R){
        if(L>R)return NULL;
        int mid=(L+R)>>1;
        Tp ret=new_node(a[mid]);
        ret->l=build(L,mid-1);
        ret->r=build(mid+1,R);
        upd(ret);
        return ret;
    }
    Tp Merge(Tp A,Tp B){
        if(!A)return B;
        if(!B)return A;
        if(A->fix<B->fix){
            pushdown(A);
            A->r=Merge(A->r,B);
            upd(A);
            return A;
        }
        else{
            pushdown(B);
            B->l=Merge(A,B->l);
            upd(B);
            return B;
        }
    }
    DTp Split(Tp A,int k){
        if(!A)return DTp(NULL,NULL);
        pushdown(A);    
        DTp y;
        if(Size(A->l)>=k){
            y=Split(A->l,k);
            A->l=y.sc;
            upd(A);
            y.sc=A;
        }
        else{
            y=Split(A->r,k-Size(A->l)-1);
            A->r=y.ft;
            upd(A);
            y.ft=A;
        }
        return y;
    }
    int pos,len;
    void Insert(){
        scanf("%d%d",&pos,&len);
        for(int i=1;i<=len;i++)scanf("%d",&a[i]);
        DTp x=Split(root,pos);
        root=Merge(x.ft,Merge(build(1,len),x.sc));
    }
    void Del(Tp A){
        if(!A)return;
        s.push(A);
        Del(A->l);
        Del(A->r);
    }
    void Delete(){
        scanf("%d%d",&pos,&len);
        DTp x=Split(root,pos-1);
        DTp y=Split(x.sc,len);
        Del(y.ft);
        root=Merge(x.ft,y.sc);
    }
    void MakeSame(){
        int v;
        scanf("%d%d%d",&pos,&len,&v);
        DTp x=Split(root,pos-1);
        DTp y=Split(x.sc,len);
        update(y.ft,v);
        root=Merge(x.ft,Merge(y.ft,y.sc));
    }
    void Rev(){
        scanf("%d%d",&pos,&len);
        DTp x=Split(root,pos-1);
        DTp y=Split(x.sc,len);
        update(y.ft,INF);
        root=Merge(x.ft,Merge(y.ft,y.sc));
    }
    int GetSum(){
        scanf("%d%d",&pos,&len);
        if(!len)return 0;
        DTp x=Split(root,pos-1);
        DTp y=Split(x.sc,len);
        int ans=y.ft->sum;
        root=Merge(x.ft,Merge(y.ft,y.sc));
        return ans;
    }
    int MaxSum(){
        return root->mx;
    }
    void init(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        root=build(1,n);
    }
    void solve(){
        char s[20];
        while(m--){
            scanf("%s",s);
            if('I'==s[0])Insert();
            else if('D'==s[0])Delete();
            else if('M'==s[0]&&'E'==s[3])MakeSame();
            else if('R'==s[0])Rev();
            else if('G'==s[0])printf("%d
    ",GetSum());
            else printf("%d
    ",MaxSum());
        }
    }
    int main()
    {
    //    freopen("testdata.in.txt","r",stdin);
    //    freopen("my.out","w",stdout);
        init();
        solve();
        return 0;
    }
  • 相关阅读:
    双六游戏 扩展欧几里得
    线段上的格点 辗转相除法(GCD)
    POJ 2395 Out of Hay
    POJ 2377 Bad Cowtractors
    POJ 1258 Agri-Net
    POJ 3169 Layout
    POJ 3723 Conscription
    次最短路径 POJ 3255 Roadblocks
    最小生成树求法 Prim + Kruskal
    如何将页脚固定在页面底部,4中方法 转载自:W3CPLUS
  • 原文地址:https://www.cnblogs.com/w-h-h/p/8111966.html
Copyright © 2020-2023  润新知