求调Treap
查看原帖
求调Treap
538609
Neutralized楼主2022/2/10 10:58

我麻了
mt19937少挂了一个点
记录1 记录2
完全不想调……打fhq去了(
谢谢您(((

#include <bits/stdc++.h>
#define ri register int
#define MAXN 2000001
#define sti static int
#define u32 unsigned int
using namespace std;

inline void Sync()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL),cout.tie(NULL);
}

namespace Mt19937{
    #define TIME chrono::system_clock::now().time_since_epoch().count()
    #ifdef debug
    u32 SEED=114514;
    #else
    u32 SEED=TIME;
    #endif
    mt19937 Random(SEED);
}; using namespace Mt19937;

namespace Treap{
    const int inf=2147483647;
    sti root,tot,val[MAXN];
    static u32 pr[MAXN];
    sti son[MAXN][2],siz[MAXN],cnt[MAXN];

    inline void update(int x){ siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x]; }
    inline void rotate(int &x,bool drct){ //father & direction
        ri ch=son[x][drct];
        son[x][drct]=son[ch][drct^1];
        son[ch][drct^1]=x;
        update(x),update(x=ch);
    } //drct=0是右旋(左儿子旋转上来)
    inline void insert(int &x,int van){
        if(!x){
            x=++tot;
            val[x]=van,siz[x]=cnt[x]=1;
            pr[x]=Random();
            return;
        } ++siz[x];
        if(val[x]==van){
            ++cnt[x];
            return;
        } register bool k=val[x]<van;
        insert(son[x][k],van);
        if(pr[x]>pr[son[x][k]]) rotate(x,k);
    }
    inline void erase(int &x,int van){
        if(!x) return;
        if(val[x]==van){
            if(cnt[x]>1){
                --cnt[x],--siz[x];
                return;
            } register bool k=pr[son[x][0]]>pr[son[x][1]];
            if(!son[x][0]||!son[x][1])
            x=son[x][0]+son[x][1];
            else rotate(x,k),erase(son[x][k^1],van);
        } else --siz[x],erase(son[x][val[x]<van],van);
    }
    inline int getrnk(int x){
        ri cur=root,ret=0;
        while(cur){
            if(val[cur]==x){
                ret+=siz[son[cur][0]];
                return ret;
            } if(val[cur]>x) cur=son[cur][0];
            else ret+=siz[son[cur][0]]+cnt[cur],cur=son[cur][1];
        } return ret;
    }
    inline int getkth(int k){
        ri cur=root;
        while(true){
            if(son[cur][0]&&siz[son[cur][0]]>=k) cur=son[cur][0];
            else{
                k-=siz[son[cur][0]]+cnt[cur];
                if(k<=0) return cur;
                cur=son[cur][1];
            }
        }
    }
    inline int prefix(int x,int van){
        if(!x) return -inf;
        if(val[x]>=van) return prefix(son[x][0],van);
        return max(prefix(son[x][1],van),val[x]);
    }
    inline int suffix(int x,int van){
        if(!x) return inf;
        if(val[x]<=van) return suffix(son[x][1],van);
        return min(suffix(son[x][0],van),val[x]);
    }
}; using namespace Treap;

int main()
{
    Sync();
    insert(root,inf),insert(root,-inf);
    ri n,opt,x;
    cin>>n;
    while(n--){
        cin>>opt>>x;
        if(opt==1) insert(root,x);
        if(opt==2) erase(root,x);
        if(opt==3) cout<<getrnk(x)<<endl;
        if(opt==4) cout<<val[getkth(x+1)]<<endl;
        if(opt==5) cout<<prefix(root,x)<<endl;
        if(opt==6) cout<<suffix(root,x)<<endl;
    }
    return 0;
}
2022/2/10 10:58
加载中...