[BZOJ1895]Pku3580 supermemo(splay)

来源:互联网 发布:js 模态窗口 编辑:程序博客网 时间:2024/05/10 15:59

题目描述

传送门

题解

splay模板题啦啦啦。
由于加了一个前驱和一个后继所以算编号的时候要小心一点。

代码

#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 300005#define inf 2100000000int n,m,x,y,d,t,p,root,sz;int a[N],f[N],ch[N][2],size[N],Min[N],key[N],add[N],rev[N];char opt[20];void clear(int x){    f[x]=ch[x][0]=ch[x][1]=size[x]=Min[x]=key[x]=add[x]=rev[x]=0;}int get(int x){    return ch[f[x]][1]==x;}void update(int x){    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;    Min[x]=key[x];    if (ch[x][0]) Min[x]=min(Min[x],Min[ch[x][0]]);    if (ch[x][1]) Min[x]=min(Min[x],Min[ch[x][1]]);}void pushdown(int x){    if (x)    {        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];            Min[ch[x][0]]+=add[x];Min[ch[x][1]]+=add[x];            key[ch[x][0]]+=add[x];key[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)>>1,now=++sz;    f[sz]=fa;key[sz]=a[mid];    int lch=build(l,mid-1,now);    int rch=build(mid+1,r,now);    ch[now][0]=lch,ch[now][1]=rch;    update(now);    return now;}void rotate(int x){    pushdown(f[x]);    pushdown(x);    int old=f[x],oldf=f[old],wh=get(x);    ch[old][wh]=ch[x][wh^1];    f[ch[old][wh]]=old;    ch[x][wh^1]=old;    f[old]=x;    if (oldf) ch[oldf][ch[oldf][1]==old]=x;    f[x]=oldf;    update(old);    update(x);}void splay(int x,int tar){    for (int fa;(fa=f[x])!=tar;rotate(x))        if (f[fa]!=tar)            rotate( (get(x)==get(fa))?fa:x );    if (!tar) root=x;}int find(int x){    int now=root;    while (1)    {        pushdown(now);        if (x<=size[ch[now][0]]) now=ch[now][0];        else        {            x-=size[ch[now][0]];            if (x==1) return now;            --x;            now=ch[now][1];        }    }}int main(){    scanf("%d",&n);    a[1]=-inf;a[n+2]=inf;    for (int i=1;i<=n;++i) scanf("%d",&a[i+1]);    root=build(1,n+2,0);    scanf("%d",&m);    for (int i=1;i<=m;++i)    {        scanf("%s",opt);        switch(opt[0])        {            case 'A':                {                    scanf("%d%d%d",&x,&y,&d);                    if (x>y) swap(x,y);                    int aa=find(x);                    int bb=find(y+2);                    splay(aa,0);                    splay(bb,aa);                    Min[ch[ch[root][1]][0]]+=d;                    add[ch[ch[root][1]][0]]+=d;                    key[ch[ch[root][1]][0]]+=d;                    update(ch[root][1]);                    update(root);                    break;                }            case 'R':                {                    if (opt[3]=='E')                    {                        scanf("%d%d",&x,&y);                        if (x==y) continue;                        if (x>y) swap(x,y);                        int aa=find(x);                        int bb=find(y+2);                        splay(aa,0);                        splay(bb,aa);                        rev[ch[ch[root][1]][0]]^=1;                    }                    else                    {                        scanf("%d%d%d",&x,&y,&t);                        if (x>y) swap(x,y);                        t%=y-x+1;                        if (!t) continue;                        int aa=find(y-t+1);                        int bb=find(y+2);                        splay(aa,0);                        splay(bb,aa);                        int now=ch[ch[root][1]][0];                        ch[ch[root][1]][0]=0;                        update(ch[root][1]);                        update(root);                        aa=find(x);                        bb=find(x+1);                        splay(aa,0);                        splay(bb,aa);                        ch[ch[root][1]][0]=now;                        f[now]=ch[root][1];                        update(ch[root][1]);                        update(root);                    }                    break;                }            case 'I':                {                    scanf("%d%d",&x,&p);                    int aa=find(x+1);                    int bb=find(x+2);                    splay(aa,0);                    splay(bb,aa);                    ch[ch[root][1]][0]=++sz;                    f[sz]=ch[root][1];                    key[sz]=Min[sz]=p;                    size[sz]=1;                    update(ch[root][1]);                    update(root);                    break;                }            case 'D':                {                    scanf("%d",&x);                    int aa=find(x);                    int bb=find(x+2);                    splay(aa,0);                    splay(bb,aa);                    int del=ch[ch[root][1]][0];                    clear(del);                    ch[ch[root][1]][0]=0;                    update(ch[root][1]);                    update(root);                    break;                }            case 'M':                {                    scanf("%d%d",&x,&y);                    if (x>y) swap(x,y);                    int aa=find(x);                    int bb=find(y+2);                    splay(aa,0);                    splay(bb,aa);                    int ans=Min[ch[ch[root][1]][0]];                    printf("%d\n",ans);                    break;                }        }    }}
0 0