[BZOJ 1895]Pku3580 supermemo:Splay

来源:互联网 发布:南京医科大学数据库 编辑:程序博客网 时间:2024/05/21 05:57

点击这里查看原题

Splay模板题,我WA了一次,TLE了两次
总结一下犯的错误就是两个:

  • pushup里默认把mn[x]设为inf而非v[x]
  • 数组开小,只开了1e5,应该至少开2e5的
/*User:SmallLanguage:C++Problem No.:1895*/#include<bits/stdc++.h>#define ll long long#define inf 999999999using namespace std;const int M=3e5+5;int n,m,a[M],rt,cnt,id[M],ch[M][2],fa[M],mn[M],v[M],siz[M],lazy[M];bool tag[M];queue<int> q;void pushup(int x){    int lson=ch[x][0],rson=ch[x][1];    siz[x]=1;    mn[x]=v[x];    if(lson){        siz[x]+=siz[lson];        mn[x]=min(mn[x],mn[lson]);    }    if(rson){        siz[x]+=siz[rson];        mn[x]=min(mn[x],mn[rson]);    }}void pushdown(int x){    int &lson=ch[x][0],&rson=ch[x][1];    if(lson){        lazy[lson]+=lazy[x];        mn[lson]+=lazy[x];        v[lson]+=lazy[x];    }    if(rson){        lazy[rson]+=lazy[x];        mn[rson]+=lazy[x];        v[rson]+=lazy[x];    }    lazy[x]=0;    if(tag[x]){        tag[lson]^=1;        tag[rson]^=1;        tag[x]^=1;        swap(lson,rson);    }}int get(int x){    return ch[fa[x]][1]==x;}void rotate(int x,int &k){    int y=fa[x],z=fa[y],side=get(x);    if(y==k) k=x;    else ch[z][ch[z][1]==y]=x;    ch[y][side]=ch[x][side^1];    fa[ch[y][side]]=y;    fa[y]=x;    ch[x][side^1]=y;    fa[x]=z;    pushup(y);    pushup(x);}void splay(int x,int &k){    while(x!=k){        if(fa[x]!=k) rotate((get(x)==get(fa[x])?fa[x]:x),k);        rotate(x,k);    }}int findx(int x){    int now=rt;    while(1){        if(tag[now]||lazy[now]) pushdown(now);        if(siz[ch[now][0]]>=x) now=ch[now][0];        else{            x-=siz[ch[now][0]]+1;            if(x<=0) return now;            now=ch[now][1];        }    }}int spilt(int l,int r){    int x=findx(l),y=findx(r+2);    splay(x,rt);splay(y,ch[x][1]);    return y;}void build(int l,int r,int f){    if(l>r) return;    int mid=l+r>>1,now=id[mid],last=id[f];    v[now]=a[mid];    if(l==r){        siz[now]=1;        mn[now]=a[mid];    }    else{        build(l,mid-1,mid);        build(mid+1,r,mid);        pushup(now);    }    fa[now]=last;    ch[last][mid>f]=now;}void add(int l,int r,int k){    int x=spilt(l,r),y=ch[x][0];    lazy[y]+=k;    mn[y]+=k;    v[y]+=k;    pushup(x);    pushup(fa[x]);}void ins(int x,int p){    int y=spilt(x+1,x);    if(!q.empty()){        id[1]=q.front();        q.pop();    }    else id[1]=++cnt;    siz[id[1]]=1;    v[id[1]]=mn[id[1]]=p;    fa[id[1]]=y;    ch[y][0]=id[1];    pushup(y);    pushup(fa[y]);}void del(int x){    int y=spilt(x,x),z=ch[y][0];    siz[z]=lazy[z]=tag[z]=v[z]=mn[z]=ch[z][0]=ch[z][1]=fa[z]=0;    q.push(z);    ch[y][0]=0;    pushup(y);    pushup(fa[y]);}int getmin(int l,int r){    int y=spilt(l,r);    return mn[ch[y][0]];}void rev(int l,int r){    int y=spilt(l,r);    tag[ch[y][0]]^=1;}void revo(int l,int r,int t){    t%=(r-l+1);    if(t==0) return;    int y=spilt(r-t+1,r),x=ch[y][0];    fa[x]=ch[y][0]=0;    pushup(y);    pushup(fa[y]);    y=spilt(l,l-1);    ch[y][0]=x;    fa[x]=y;    pushup(y);    pushup(fa[y]);}int main(){    freopen("data.in","r",stdin);//    scanf("%d",&n);    a[1]=a[n+2]=inf;    for(int i=2;i<=n+1;i++)        scanf("%d",&a[i]);    for(int i=1;i<=n+2;i++) id[i]=i;    rt=(n+3)>>1,cnt=n+2;    build(1,n+2,0);    scanf("%d",&m);    while(m--){        char op[15];        int x,y,p;        scanf("%s%d",op,&x);        switch(op[0]){            case 'D':n--;del(x);break;            case 'I':{                scanf("%d",&p);                n++;                ins(x,p);                break;            }            case 'A':{                scanf("%d%d",&y,&p);                if(x>y) swap(x,y);                add(x,y,p);                break;            }            case 'M':{                scanf("%d",&y);                printf("%d\n",getmin(x,y));                break;            }            case 'R':{                if(op[3]=='E'){                    scanf("%d",&y);                    if(x==y) continue;                    if(x>y) swap(x,y);                    rev(x,y);                }                else{                    scanf("%d%d",&y,&p);                    if(x>y) swap(x,y);                    revo(x,y,p);                }                break;            }        }    }    return 0;}
0 0
原创粉丝点击