bzoj1895: Pku3580 supermemo

来源:互联网 发布:淘宝 跑腿 编辑:程序博客网 时间:2024/05/21 05:18

传送门
发现题目中的所有东西都可以用splay维护
然后就理所应当的成了splay裸题了。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cstdlib>#include<cmath>#define N 300030using namespace std;int n,m,x,y,d,t,p,rt,cnt;int a[N],f[N],ch[N][2],sz[N],mn[N],key[N],add[N],rev[N];char s[20];void clear(int x){    f[x]=ch[x][0]=ch[x][1]=sz[x]=0;    mn[x]=key[x]=add[x]=rev[x]=0;}int get(int x){    return ch[f[x]][1]==x;}void update(int x){    sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;    mn[x]=key[x];    if (ch[x][0]) mn[x]=min(mn[x],mn[ch[x][0]]);    if (ch[x][1]) mn[x]=min(mn[x],mn[ch[x][1]]);}void pushdown(int x){    if (!x) return;    if (rev[x]){        rev[ch[x][0]]^=1;        rev[ch[x][1]]^=1;        swap(ch[x][0],ch[x][1]);        rev[x]=0;    }    if (add[x]){        add[ch[x][0]]+=add[x],add[ch[x][1]]+=add[x];        key[ch[x][0]]+=add[x],key[ch[x][1]]+=add[x];        mn[ch[x][0]]+=add[x],mn[ch[x][1]]+=add[x];        add[x]=0;    }}int build(int l,int r,int fa){    if (l>r) return 0;    int mid=(l+r)/2,x=++cnt;    f[x]=fa; key[x]=a[mid];    ch[x][0]=build(l,mid-1,x);    ch[x][1]=build(mid+1,r,x);    update(x);    return x;}void rotate(int x){    pushdown(f[x]); pushdown(x);    int y=f[x],z=f[y],l=get(x),r=l^1;    if (z) ch[z][get(y)]=x;    f[x]=z; f[y]=x; f[ch[x][r]]=y;    ch[y][l]=ch[x][r]; ch[x][r]=y;    update(y); update(x);}void splay(int x,int tar){    for (;f[x]!=tar;rotate(x))        if (f[f[x]]!=tar)            rotate(get(x)==get(f[x])?f[x]:x);    if (!tar) rt=x;}int find(int rk){    int x=rt;    while(1){        pushdown(x);        if (rk<=sz[ch[x][0]]) x=ch[x][0];        else{            rk-=sz[ch[x][0]]+1;            if (!rk) return x;            x=ch[x][1];        }    }}void pre(int x,int y){    int a=find(x),b=find(y);    splay(a,0); splay(b,a);}void up(){    update(ch[rt][1]);    update(rt);}int main(){    scanf("%d",&n);    a[1]=2e9; a[n+2]=-2e9;    for (int i=2;i<=n+1;i++) scanf("%d",&a[i]);    rt=build(1,n+2,0);    scanf("%d",&m);    while (m--){        scanf("%s",s);        if (s[0]=='A'){            scanf("%d%d%d",&x,&y,&d);            if (x>y) swap(x,y);            pre(x,y+2);            mn[ch[ch[rt][1]][0]]+=d;            add[ch[ch[rt][1]][0]]+=d;            key[ch[ch[rt][1]][0]]+=d;            up();        }        else if (s[0]=='I'){            scanf("%d%d",&x,&p);            pre(x+1,x+2);            ch[ch[rt][1]][0]=++cnt;            f[cnt]=ch[rt][1];            key[cnt]=mn[cnt]=p;            sz[cnt]=1;            up();        }        else if (s[0]=='D'){            scanf("%d",&x);            pre(x,x+2);            int del=ch[ch[rt][1]][0];            clear(del);            ch[ch[rt][1]][0]=0;            up();         }        else if (s[0]=='M'){            scanf("%d%d",&x,&y);            if (x>y) swap(x,y);            pre(x,y+2);            printf("%d\n",mn[ch[ch[rt][1]][0]]);        }        else if (s[3]=='E'){            scanf("%d%d",&x,&y);            if (x==y) continue;            pre(x,y+2);            rev[ch[ch[rt][1]][0]]^=1;        }        else{            scanf("%d%d%d",&x,&y,&t);            if (x>y) swap(x,y);            t%=(y-x+1);            if (!t) continue;            pre(y-t+1,y+2);            int now=ch[ch[rt][1]][0];            ch[ch[rt][1]][0]=0;            up();            pre(x,x+1);            ch[ch[rt][1]][0]=now;            f[now]=ch[rt][1];            up();        }    }}