BZOJ1895: Pku3580 supermemo

http://www.lydsy.com/JudgeOnline/problem.php?id=1895

  用来练习fhq_treap的题。

#include<bits/stdc++.h>
const int maxn=100015;
using namespace std;
int n,m,a[maxn];
struct Ttreap{
    int tot;
    static const int maxnode=2000015;
    struct Tnode{
        Tnode *c[2];bool rev;
        int key,siz,add,val,fmn;
        void update(){
            siz=c[0]->siz+c[1]->siz+1;
            fmn=min(c[0]->fmn,c[1]->fmn);fmn=min(fmn,val);
        }
        void add_rev(){if (siz){rev^=1;swap(c[0],c[1]);}}
        void add_add(int v){if (siz){add+=v;val+=v;fmn+=v;}}
        void clear(){
            if (!siz) return;
            if (rev){c[0]->add_rev();c[1]->add_rev();rev=0;}
            if (add){c[0]->add_add(add);c[1]->add_add(add);add=0;}
        }
    }T[maxnode],*null,*root;
    void clear(){
        tot=0;null=T;
        null->c[0]=null->c[1]=null;
        null->siz=null->add=null->rev=0;
        null->fmn=null->val=2147483647;
    }
    Tnode *newnode(int v){
        Tnode *cur=T+(++tot);
        cur->c[0]=cur->c[1]=null;
        cur->siz=1;cur->add=cur->rev=0;
        cur->val=cur->fmn=v;cur->key=rand();
        return cur;
    }
    void build(){
        static Tnode *stk[maxn];int top=0;
        for (int i=1;i<=n;++i){
            Tnode *cur=newnode(a[i]),*last=null;
            while (top&&stk[top]->key>cur->key){stk[top]->update();last=stk[top--];}
            cur->c[0]=last;cur->update();if (top) stk[top]->c[1]=cur;
            stk[++top]=cur;
        }
        while (top) stk[top--]->update();
        root=stk[1];
    }
    Tnode *merge(Tnode *x,Tnode *y){
        if (x==null) return y;
        if (y==null) return x;
        x->clear();y->clear();
        if (x->key<y->key){x->c[1]=merge(x->c[1],y);x->update();return x;}
        else{y->c[0]=merge(x,y->c[0]);y->update();return y;}
    }
    pair<Tnode*,Tnode*> split(Tnode *x,int rank){
        if (!rank) return make_pair(null,x);
        x->clear();pair<Tnode*,Tnode*> y;
        if (rank<=x->c[0]->siz){
            y=split(x->c[0],rank);
            x->c[0]=y.second;x->update();y.second=x;
        }
        else{
            y=split(x->c[1],rank-x->c[0]->siz-1);
            x->c[1]=y.first;x->update();y.first=x;
        }
        return y;
    }
    void add(int l,int r,int v){
        pair<Tnode*,Tnode*> y=split(root,l-1);
        pair<Tnode*,Tnode*> z=split(y.second,r-l+1);
        z.first->add_add(v);
        root=merge(y.first,z.first);root=merge(root,z.second);
    }
    int query(int l,int r){
        pair<Tnode*,Tnode*> y=split(root,l-1);
        pair<Tnode*,Tnode*> z=split(y.second,r-l+1);
        int res=z.first->fmn;
        root=merge(y.first,z.first);root=merge(root,z.second);
        return res;
    }
    void insert(int pos,int v){
        pair<Tnode*,Tnode*> y=split(root,pos);
        Tnode *cur=newnode(v);
        root=merge(y.first,cur);root=merge(root,y.second);
    }
    void remove(int pos){
        pair<Tnode*,Tnode*> y=split(root,pos-1);
        pair<Tnode*,Tnode*> z=split(y.second,1);
        root=merge(y.first,z.second);
    }
    void reverse(int l,int r){
        pair<Tnode*,Tnode*> y=split(root,l-1);
        pair<Tnode*,Tnode*> z=split(y.second,r-l+1);
        z.first->add_rev();
        root=merge(y.first,z.first);root=merge(root,z.second);
    }
    void revolve(int l,int r,int t){
        t%=(r-l+1);if (!t) return;
        pair<Tnode*,Tnode*> y=split(root,l-1);
        pair<Tnode*,Tnode*> z=split(y.second,r-l+1);
        pair<Tnode*,Tnode*> w=split(z.first,r-l+1-t);
        root=merge(w.second,w.first);root=merge(y.first,root);root=merge(root,z.second);
    }
}treap;
void init(){
    scanf("%d",&n);srand(19990917);
    for (int i=1;i<=n;++i) scanf("%d",&a[i]);
    scanf("%d",&m);treap.clear();treap.build();
}
void add(){
    int x,y,v;scanf("%d%d%d",&x,&y,&v);
    treap.add(x,y,v);
}
void query(){
    int x,y;scanf("%d%d",&x,&y);
    printf("%d\n",treap.query(x,y));
}
void insert(){
    int x,v;scanf("%d%d",&x,&v);
    treap.insert(x,v);
}
void remove(){
    int x;scanf("%d",&x);
    treap.remove(x);
}
void reverse(){
    int x,y;scanf("%d%d",&x,&y);
    treap.reverse(x,y);
}
void revolve(){
    int x,y,t;scanf("%d%d%d",&x,&y,&t);
    treap.revolve(x,y,t);
}
void work(){
    for (int i=1;i<=m;++i){
        char op[10];scanf("%s",op);
        switch (op[0]){
            case 'A':add();break;
            case 'M':query();break;
            case 'I':insert();break;
            case 'D':remove();break;
            case 'R':op[3]=='E'?reverse():revolve();break;
        }
    }
}
int main(){
    init();
    work();
    return 0;
}
my code

 

posted @ 2015-08-19 21:26  iamCYY  阅读(214)  评论(0编辑  收藏  举报