1. 程式人生 > 其它 >【模板】fhq-Treap

【模板】fhq-Treap

傳送門

  1. 插入xx數
  2. 刪除xx數(若有多個相同的數,因只刪除一個)
  3. 查詢xx數的排名(排名定義為比當前數小的數的個數+1+1)
  4. 查詢排名為xx的數
  5. xx的前驅(前驅定義為小於xx,且最大的數)
  6. xx的後繼(後繼定義為大於xx,且最小的數)
#include<iostream>
#include<cstdio>
#define INF 0x3f3f3f3f
using namespace std;
int n,op,x,c_x,c_y;
int root,t[100050][2],Size[100050],val[100050],td;
unsigned long long zz=998244353
; int Rank(){ return zz=(int)(zz*1000000007); } void update(int x) { Size[x]=Size[t[x][0]]+Size[t[x][1]]+1; } void split(int x,int k) { if(!x){ c_x=c_y=0; return; } if(Size[t[x][0]]<k){ split(t[x][1],k-(Size[t[x][0]]+1)); t[x][1]=c_x; c_x=x; }
else{ split(t[x][0],k); t[x][0]=c_y; c_y=x; } update(x); } int merge(int a, int b) { if(a==0||b==0) return a+b; if(Rank()%(Size[a]+Size[b])<Size[a]) { t[a][1]=merge(t[a][1],b); update(a); return a; } else{ t[b][0]=merge(a,t[b][0
]); update(b); return b; } } int val_rank(int x,int k) { if(!x) return 0; if(val[x]>=k) return val_rank(t[x][0],k); return val_rank(t[x][1],k)+Size[t[x][0]]+1; } void ins(int k) { val[++td]=k; Size[td]=1; split(root,val_rank(root,k)); root=merge(c_x,td); root=merge(root,c_y); } void del(int k) { split(root,val_rank(root,k)); root=c_x; split(c_y,1); root=merge(root,c_y); } int rank_val(int x,int k) { if(Size[t[x][0]]>=k) return rank_val(t[x][0],k); if(Size[t[x][0]]+1==k) return val[x]; return rank_val(t[x][1],k-Size[t[x][0]]-1); } int pre(int x,int k) { if(!x) return INF; if(val[x]<k) { int p=pre(t[x][1],k); if(p==INF) return val[x]; return p; } return pre(t[x][0],k); } int nxt(int x,int k) { if(!x) return INF; if(val[x]>k) { int p=nxt(t[x][0],k); if(p==INF) return val[x]; return p; } return nxt(t[x][1],k); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&op,&x); if(op==1) ins(x); if(op==2) del(x); if(op==3) printf("%d\n",val_rank(root,x)+1); if(op==4) printf("%d\n",rank_val(root,x)); if(op==5) printf("%d\n",pre(root,x)); if(op==6) printf("%d\n",nxt(root,x)); } }