Splay TLE on #10 求助

P6136 【模板】普通平衡树(数据加强版)

WCPWCPWCP @ 2022-08-25 19:06:45

#include<iostream>
#include<climits>
#define maxn 2000010
using namespace std;

struct node{
    int s[2],p,cnt,v,siz;
    void init(int p1,int v1){
        p=p1,v=v1;
        cnt=siz=1;
    }
}tr[maxn];
int root,idex,ans=0,last=0;
int read(){
    int res=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-'){
            f=f*-1;
        }
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        res=res*10+c-'0';
        c=getchar();
    }
    return res*f;
}
void write(int x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
void pushup(int node){
    tr[node].siz=tr[tr[node].s[0]].siz+tr[tr[node].s[1]].siz+tr[node].cnt;
}
void rotate(int x){
    int y=tr[x].p,z=tr[y].p;
    int k=tr[y].s[1]==x;
    tr[y].s[k]=tr[x].s[k^1];
    tr[tr[x].s[k^1]].p=y;
    tr[x].s[k^1]=y;
    tr[y].p=x;
    tr[x].p=z;
    tr[z].s[tr[z].s[1]==y]=x;
    pushup(y);
    pushup(x);
}
void splay(int x,int u){
    while(tr[x].p!=u){
        int y=tr[x].p,z=tr[y].p;
        if(z!=u){
            if((tr[z].s[0]==y)^(tr[y].s[0]==x)){
                rotate(x);
            }
            else{
                rotate(y);
            }
        }
        else{
            rotate(x);
        }
    }
    if(u==0) root=x;
}
void find(int v){
    int x=root;
    while(tr[x].s[v>tr[x].v]&&v!=tr[x].v){   //  ???
        x=tr[x].s[v>tr[x].v];
    }
    splay(x,0);
}
int find_xrk(int x){   // 需要保证查找的数在树里面 ,也可以先加入一个数再删除掉 
    find(x);
    return tr[tr[root].s[0]].siz; 
}
inline int getrank(int x){  // 不需要保证数在树里面 
    int cur=root,ret=0;
    while(cur){
        if(tr[cur].v==x){
            ret+=tr[tr[cur].s[0]].siz;
            splay(cur,0); return ret;
        } 
        if(tr[cur].v>x)
        cur=tr[cur].s[0];
        else
        ret+=tr[tr[cur].s[0]].siz+tr[cur].cnt,cur=tr[cur].s[1];
    } 
    if(tr[cur].v==x){
        splay(cur,0);
    }
    else{
        splay(tr[cur].p,0);
    }
    return ret;
}
int find_rkx(int k){
    int x=root;
    while(1){
        if(tr[x].cnt+tr[tr[x].s[0]].siz<k){
            k-=tr[x].cnt+tr[tr[x].s[0]].siz;
            x=tr[x].s[1];
        }
        else{
            if(tr[tr[x].s[0]].siz>=k){
                x=tr[x].s[0];
            }
            else{
                break;
            }
        }
    }
    splay(x,0);
    return tr[x].v;
}
int find_pre(int v){
    find(v);
    int x=root;
    if(tr[x].v<v){
        return x;
    }
    x=tr[x].s[0];
    while(tr[x].s[1]){
        x=tr[x].s[1];
    }
    //splay(x,0);
    return x;
}
int find_rea(int v){
    find(v);
    int x=root;
    if(tr[x].v>v){
        return x;
    }
    x=tr[x].s[1];
    while(tr[x].s[0]){
        x=tr[x].s[0];
    }
    //splay(x,0);
    return x;
}
void ldelete(int x){
    int pre=find_pre(x);
    int rea=find_rea(x);
    splay(pre,0);
    splay(rea,pre);
    if(tr[tr[rea].s[0]].cnt>1){
        tr[tr[rea].s[0]].cnt--;
        splay(tr[rea].s[0],0);
    }
    else{
        tr[rea].s[0]=0;
        splay(rea,0);
    }
}
void insert(int v){
    int x=root,p=0;
    while(x&&tr[x].v!=v){
        p=x;x=tr[x].s[v>tr[x].v];
    }
    if(x) tr[x].cnt++;
    else{
        x=++idex;
        tr[p].s[v>tr[p].v]=x;
        tr[x].init(p,v);
    }
    splay(x,0);
}

int main()
{
    int n,m;
    n=read(),m=read();
    insert(-INT_MAX);
    insert(INT_MAX);
    for(int i=1;i<=n;i++){
        int a;
        a=read();
        insert(a);
    }
    for(int i=1;i<=m;i++){
        int op,x;
        op=read(),x=read(); 
        x=(x^last);
        if(op==1){
            insert(x);
        }
        else if(op==2){
            ldelete(x);
        }
        else if(op==3){
            int tmp=getrank(x);
            ans^=tmp;
            last=tmp;
        }
        else if(op==4){
            int tmp=find_rkx(x+1);
            ans^=tmp;
            last=tmp;
        }
        else if(op==5){
            int tmp=tr[find_pre(x)].v;
            ans^=tmp;
            last=tmp;
        }
        else if(op==6){
            int tmp=tr[find_rea(x)].v;
            ans^=tmp;
            last=tmp;
        }
    }
    write(ans);
    return 0;
}

by WCPWCPWCP @ 2022-08-25 21:27:12

第10个点一直是tle的,qaq


by WCPWCPWCP @ 2022-08-26 10:14:26

第10个点只有插入和删除操作,插入的时候正常,删除的时候跑很慢


by WCPWCPWCP @ 2022-08-26 11:06:51

此贴终

if((tr[z].s[0]==y)^(tr[y].s[0]==x)){
    rotate(x);
}
else{
    rotate(y);
}

不应该要else的,警示后人qaq


|