splay跑了15秒正常吗

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

Eddy2008 @ 2022-02-08 10:59:17

如题,参考这篇博文写的,结果跑出了14.79秒的良好成绩。请问这正常吗?是我常数太大了吗?

代码:

#include<bits/stdc++.h>
#define maxn 1100010
using namespace std;
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-'0';ch=getchar();}
    return x*f;
}
int n,m;
struct Splay{
    int root=0,tol=0,fa[maxn],ch[maxn][2],val[maxn],cnt[maxn],siz[maxn];
    inline void update(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];}
    inline bool get(int x){return x==ch[fa[x]][1];}
    inline void rotate(int x){
        int y=fa[x],z=fa[y],chk=get(x);
        ch[y][chk]=ch[x][!chk], fa[ch[x][!chk]]=y;
        ch[x][!chk]=y, fa[y]=x;
        fa[x]=z, ch[z][y==ch[z][1]]=x;
        update(y);
    }
    inline void splay(int x){
        for(int p=fa[x];p;rotate(x), p=fa[x])
            if(fa[p]) rotate(get(x)==get(p) ? p : x);
        root=x;
    }
    inline void insert(int v){
        if(!root){
            val[++tol]=v, cnt[tol]=1;
            root=tol, update(tol);
            return;
        }
        int p=root,f=0;
        while(1){
            if(val[p]==v){
                cnt[p]++;
                update(p), update(f);
                splay(p);
                return;
            }
            f=p, p=ch[p][v>val[p]];
            if(!p){
                val[++tol]=v, cnt[tol]++;
                fa[tol]=f, ch[f][v>val[f]]=tol;
                update(tol), update(f);
                splay(tol); 
                return;
            }
        }
    }
    inline int getrank(int v){
        int p=root,ans=0;
        while(1){
            if(v<val[p]) p=ch[p][0];
            else{
                ans+=siz[ch[p][0]];
                if(val[p]==v){splay(p); return ans+1;}
                ans+=cnt[p], p=ch[p][1];
            }
        }
    }
    inline int getval(int k){
        int p=root;
        while(1){
            if(ch[p][0] && siz[ch[p][0]]>=k) p=ch[p][0];
            else{
                k-=siz[ch[p][0]];
                if(k<=cnt[p]){splay(p); return val[p];}
                k-=cnt[p], p=ch[p][1];
            }
        }
    }
    inline int pre(){
        int p=ch[root][0];  
        while(ch[p][1]) p=ch[p][1];
        if(p) splay(p);
        return p;
    }
    inline int nxt(){
        int p=ch[root][1];
        while(ch[p][0]) p=ch[p][0];
        if(p) splay(p);
        return p;
    }
    inline void remove(int v){
        getrank(v);
        if(cnt[root]>1) cnt[root]--, update(root);
        else if(!ch[root][0] && !ch[root][1]) root=0;
        else if(!ch[root][0]) root=ch[root][1], fa[root]=0;
        else if(!ch[root][1]) root=ch[root][0], fa[root]=0;
        else{
            int p=root; root=pre();
            fa[ch[p][1]]=root, ch[root][1]=ch[p][1];
            update(root);
        }
    }
};
Splay T;
int main(){
    n=read(), m=read();
    for(int i=1;i<=n;i++) T.insert(read());
    int ans=0,last=0;
    for(int i=1,op,x;i<=m;i++){
        op=read(), x=read();
        x=x^last;
        if(op==1) T.insert(x);
        else if(op==2) T.remove(x);
        else if(op==3){
            T.insert(x);
            last=T.getrank(x);
            T.remove(x);
            ans^=last;
        }
        else if(op==4){
            last=T.getval(x);
            ans^=last;
        }
        else if(op==5){
            T.insert(x);
            last=T.val[T.pre()];
            T.remove(x);
            ans^=last;
        }
        else if(op==6){
            T.insert(x);
            last=T.val[T.nxt()];
            T.remove(x);
            ans^=last;
        }
    }
    printf("%d",ans);
    return 0;
}

by RuSun @ 2022-02-08 11:08:59

splay 我的 8s


by eigw22h619 @ 2022-02-08 20:51:38

不太正常,可能是因为你的操作3、5、6都调用了3个函数。我的 splay 6.66s。


|