splay 求条(玄关)
查看原帖
splay 求条(玄关)
749665
huta0楼主2024/3/25 19:58
 #include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define a_all a.begin(),a.end()
using namespace std;
typedef long long ll;
int n,op,x;
namespace hikari {
      struct node {
           int p,v,cnt,size;
           int s[2];
           void init(int pp,int vv) {
                p=pp,v=vv;
                cnt=size=1;
           }
      } tr[100010];
      #define fa(x) tr[x].p
      #define lc(x) tr[x].s[0]
      #define rc(x) tr[x].s[1]
      int rt,tot=0;
      void pushup(int x) {
            tr[x].size=tr[lc(x)].size+tr[rc(x)].size+tr[x].cnt;
      }
      void rotate(int x) {
            int y=fa(x),z=fa(y);
            int k= rc(y)==x;
            tr[z].s[rc(z)==y]=x;
            fa(x)=z;
            tr[y].s[k]=tr[x].s[k^1];
            fa(tr[x].s[k^1])=y;
            tr[x].s[k^1]=y;
            fa(y)=x;
            pushup(y); pushup(x);
      }
      void splay(int x,int v) {
            while(fa(x)!=v) {
                  int y=fa(x),z=fa(y);
                  if(z!=v) rotate(lc(y)==x^lc(z)==y?x:y);
                  rotate(x);
            }
            if(v==0) rt=x;
      }
      void find(int v) {
             int x=rt;
             while(tr[x].s[v>tr[x].v]&&v!=tr[x].v)
                   x=tr[x].s[v>tr[x].v];
             splay(x,0);
      }
      int pre(int v) {
             find(v);
             int x=rt;
             if(tr[x].v<v) return x;
             x=lc(x);
             while(rc(x)) x=rc(x);
             splay(x,0);
             return x;
      }
      int suc(int v) {
             find(v);
             int x=rt;
             if(tr[x].v>v) return x;
             x=rc(x);
             while(lc(x)) x=lc(x);
             splay(x,0);
             return x;
      }
      void del(int x) {
            int pr=pre(x);
            int sc=suc(x);
            splay(pr,0); splay(sc,pr);
            int del=lc(sc);
            if(tr[del].cnt>1) tr[del].cnt--,splay(del,0);
            else tr[sc].s[0]=0,splay(sc,0);
      }
      int rank(int x) {
            find(x);
            return tr[lc(rt)].size;
      }
      int val(int rk) {
            int x=rt; ++rk;
            while(1) {
                  int y=lc(x);
                  if(tr[y].size+tr[x].cnt<rk) {
                       rk-=tr[y].size+tr[x].cnt;
                       x=rc(x);
                  } else {
                       if(tr[y].size>=rk) x=lc(x);
                       else break;
                  }
            }
            splay(x,0);
            return tr[x].v;
      }
      void insert(int v) {
            int x=rt,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=++tot;
                  tr[p].s[v>tr[p].v]=x;
                  tr[x].init(p,v);
            }
            splay(x,0);
      }
}
using namespace hikari;
int main() {
    cin.tie(0);
    cout.tie(0);
    insert(-1e9); insert(1e9);
    cin>>n;
    rep(i,1,n) {
          cin>>op>>x;
          if(op==1) insert(x);
          else if(op==2) del(x);
          else if(op==3) cout<<hikari::rank(x)<<endl;
          else if(op==4) cout<<val(x)<<endl;
          else if(op==5) cout<<tr[pre(x)].v<<endl;
          else cout<<tr[suc(x)].v<<endl;
    }
    return 0;
}
2024/3/25 19:58
加载中...