wa点14,tle4,15,18-23,求调悬1关

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

leiaxiwo @ 2024-04-19 12:39:03

好像是数组大小问题,splay写法,性能没问题啊

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int root,tot;
struct splay_tree{
    int ch[2],siz,cnt,fa,val;
}tree[3000005];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
inline void put(int x)
{
    if(x==0)
    {
        putchar('0');
        putchar('\n');
        return;
    }
    int num=0;
    char c[25];
    while(x){
        c[++num]=(x%10)+48;
        x/=10;
    }
    while(num)
        putchar(c[num--]);
    putchar('\n');
    return ;
}
void update(int x){
    tree[x].siz=tree[tree[x].ch[0]].siz+tree[tree[x].ch[1]].siz+tree[x].cnt;
    return ;
}
bool get(int x){
    return x==tree[tree[x].fa].ch[1];
}
void rotate(int x)
{
    int y=tree[x].fa,z=tree[y].fa,chk=get(x);
    tree[y].ch[chk]=tree[x].ch[chk^1];
    if(tree[x].ch[chk^1])
        tree[tree[x].ch[chk^1]].fa=y;
    tree[x].ch[chk^1]=y;
    tree[y].fa=x;
    tree[x].fa=z;
    if(z)
        tree[z].ch[y==tree[z].ch[1]]=x;
    update(y);
    update(x);
    return ;
}
void splay(int x){
    for(int f=tree[x].fa;f=tree[x].fa,f;rotate(x))
        if(tree[f].fa)
            rotate(get(x)==get(f)?f:x);
    root=x;
}
void clear(int x){
    tree[x].ch[0]=tree[x].ch[1]=tree[x].fa=tree[x].val=tree[x].cnt=tree[x].siz=0;
    return ;
}
void insert(int k)
{
    if(!root)
    {
        tree[++tot].val=k;
        tree[tot].cnt++;
        root=tot;
        update(root);
        return;
    }
    int cur=root,f=0;
    while(1)
    {
        if(tree[cur].val==k)
        {
            tree[cur].cnt++;
            update(cur);
            update(f);
            splay(cur);
            break;
        }
        f=cur;
        cur=tree[f].ch[tree[f].val<k];
        if(!cur)
        {
            tree[++tot].val=k;
            tree[tot].cnt++;
            tree[tot].fa=f;
            tree[f].ch[tree[f].val<k]=tot;
            update(tot);
            update(f);
            splay(tot);
            break;
        }
    }
}
int rnk(int x){
    int res=0,cur=root;
    while(1){
        if(x<tree[cur].val)
            cur=tree[cur].ch[0];
        else{
            res+=tree[tree[cur].ch[0]].siz;
            if(x==tree[cur].val){
                splay(cur);
                return res+1;
            }
            res+=tree[cur].cnt;
            cur=tree[cur].ch[1];
        }
    }
}
int kth(int x){
    int cur=root;
    while(1){
        if(tree[cur].ch[0]&&x<=tree[tree[cur].ch[0]].siz){
            cur=tree[cur].ch[0];
        }
        else{
            x-=tree[tree[cur].ch[0]].siz+tree[cur].cnt;
            if(x<=0){
                splay(cur);
                return tree[cur].val;
            }
            cur=tree[cur].ch[1];
        }
    }
}
int pre(){
    int cur=tree[root].ch[0];
    if(!cur){
        return cur;
    }
    while(tree[cur].ch[1]){
        cur=tree[cur].ch[1];
    }
    splay(cur);
    return cur;
}
int next(){
    int cur=tree[root].ch[1];
    if(!cur){
        return cur;
    }
    while(tree[cur].ch[0]){
        cur=tree[cur].ch[0];
    }
    splay(cur);
    return cur;
}
void del(int x){
    rnk(x);
    if(tree[root].cnt>1){
        tree[root].cnt--;
        update(root);
        return ;
    }
    if(!tree[root].ch[0]&&!tree[root].ch[1]){
        clear(root);
        root=0;
        return ;
    }
    if(!tree[root].ch[0]){
        int cur=root;
        root=tree[root].ch[1];
        tree[root].fa=0;
        clear(cur);
        return ;
    }
    if(!tree[root].ch[1]){
        int cur=root;
        root=tree[root].ch[0];
        tree[root].fa=0;
        clear(cur);
        return ;
    }
    int cur=root;
    pre();
    tree[tree[cur].ch[1]].fa=root;
    tree[root].ch[1]=tree[cur].ch[1];
    clear(cur);
    update(root);
    return ;
}
int last,ans;
signed main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++){
        int x=read();
        insert(x);
    }
    for(int i=1;i<=m;i++){
        int opt=read(),x=read()^last;
        if(opt==1){
            insert(x);
        }
        else if(opt==2){
            del(x);
        }
        else if(opt==3){
            insert(x);
            last=rnk(x);
            del(x);
            ans^=last;
        }
        else if(opt==4){
            insert(x);
            last=kth(x);
            del(x);
            ans^=last;
        }
        else if(opt==5){
            insert(x);
            last=tree[pre()].val;
            del(x);
            ans^=last;
        }
        else if(opt==6){
            insert(x);
            last=tree[next()].val;
            del(x);
            ans^=last;
        }
    }
    put(ans);
    return 0;
}

by Yuzilihhh @ 2024-05-05 11:46:08

void splay(int x){
    for(int f=tree[x].fa;f=tree[x].fa,f;rotate(x))
        if(tree[f].fa)
            rotate(get(x)==get(f)?f:x);
    root=x;
}

第二行代码中,f=tree[x].fa会改变f的大小。

还有,剩下部分我没看,不过同为写Splay的人要记得多Splay几次,树会更平衡


|