2 条题解

  • 1
    @ 2024-11-21 20:30:12

    FHQ Treap

    在竞赛中我们一般使用FHQ Treap这种弱平衡的二叉搜索树。(又称无旋Treap)

    它只有分裂与合并两种操作,相当好写。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+7;
    mt19937 rd(time(0));
    struct node{
        int l,r,val,pri,size;
    }t[N];
    int cnt,root;
    int newnode(int x){
        cnt++;
        t[cnt].l=t[cnt].r=0;
        t[cnt].size=1;
        t[cnt].val=x;
        t[cnt].pri=rd();
        return cnt;
    }
    void update(int u){
        t[u].size=t[t[u].l].size+t[t[u].r].size+1;
        return ;
    }
    void split(int u,int x,int &l,int &r){
        if(u==0){
            l=r=0;
            return ;
        }
        if(t[u].val<=x){
            l=u;
            split(t[u].r,x,t[u].r,r);
        }else {
            r=u;
            split(t[u].l,x,l,t[u].l);
        }
        update(u);
        return ;
    }
    int merge(int l,int r){
        if(!l||!r)return r+l;
        if(t[l].pri>t[r].pri){
            t[l].r=merge(t[l].r,r);
            update(l);
            return l;
        }else {
            t[r].l=merge(l,t[r].l);
            update(r);
            return r;
        }
    }
    void insert(int x){
        int l,r;
        split(root,x,l,r);
        root=merge(merge(l,newnode(x)),r);
        return ;
    }
    void del(int x){
        int l,r,p;
        split(root,x,l,r);
        split(l,x-1,l,p);
        p=merge(t[p].l,t[p].r);
        root=merge(merge(l,p),r);
        return ;
    }
    void xth(int x){
        int l,r;
        split(root,x-1,l,r);
        cout<<t[l].size+1<<'\n';
        root=merge(l,r);
        return ;
    }
    int kth(int u,int k){
        if(k==t[t[u].l].size+1)return u;
        if(k<=t[t[u].l].size)return kth(t[u].l,k);
        else return kth(t[u].r,k-t[t[u].l].size-1);
    }
    void preor(int x){
        int l,r;
        split(root,x-1,l,r);
        cout<<t[kth(l,t[l].size)].val<<'\n';
        root=merge(l,r);
        return ;
    }
    void sucor(int x){
        int l,r;
        split(root,x,l,r);
        cout<<t[kth(r,1)].val<<'\n';
        root=merge(l,r);
        return ;
    }
    int main(){
        int n;
        cin>>n;
        while(n--){
            int opt,x;
            cin>>opt>>x;
            if(opt==1)insert(x);
            else if(opt==2)del(x);
            else if(opt==3)xth(x);
            else if(opt==4)cout<<t[kth(root,x)].val<<'\n';
            else if(opt==5)preor(x);
            else sucor(x);
        }
        return 0;
    }
    

    信息

    ID
    15132
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    9
    已通过
    7
    上传者