1. 旋转treap。
思想:一颗权值BST + 一颗 随机数 最小堆。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; #define inf 300000030 const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; struct Treap{ int L[N], R[N], sz[N], v[N], rnd[N], ct[N], tot, root; void init(){ tot = root = 0; } inline int rand(){ static int seed = 12345; return seed = (int)seed * 482711LL % 2147483647; } void Updata(int p){ sz[p] = ct[p] + sz[L[p]] + sz[R[p]]; } void turnL(int &k){ int t = R[k]; R[k] = L[t]; L[t] = k; sz[t] = sz[k]; Updata(k); k = t; } void turnR(int &k){ int t = L[k]; L[k] = R[t]; R[t] = k; sz[t] = sz[k]; Updata(k); k = t; } void Insert(int &p, int x){ if(!p){ p = ++tot; sz[p] = ct[p] = 1; v[p] = x; rnd[p] = rand(); return ; } sz[p]++; if(v[p] == x) ct[p]++; else if(x > v[p]){ Insert(R[p], x); if(rnd[R[p]] < rnd[p]) turnL(p); } else { Insert(L[p], x); if(rnd[L[p]] < rnd[p]) turnR(p); } } void Delete(int &p, int x){ if(!p) return ; if(v[p] == x){ if(ct[p] > 1) ct[p]--, sz[p]--; else { if(L[p] == 0 || R[p] == 0) p = L[p] + R[p]; else if(rnd[L[p]] < rnd[R[p]]) turnR(p), Delete(p, x); else turnL(p), Delete(p, x); } } else if(x > v[p]) sz[p]--, Delete(R[p], x); else sz[p]--, Delete(L[p], x); } int Query_Rank_of_x(int p, int x){ if(!p) return 0; if(v[p] == x) return sz[L[p]]+1; if(v[p] > x) return Query_Rank_of_x(L[p], x); return ct[p] + sz[L[p]] + Query_Rank_of_x(R[p], x); } int Query_kth(int p, int k){ if(!p) return -1; if(sz[L[p]] >= k) return Query_kth(L[p], k); k -= sz[L[p]]; if(k <= ct[p]) return v[p]; k -= ct[p]; return Query_kth(R[p], k); } int FindFront(int p, int x){ if(!p) return -inf; if(v[p] < x) return max(v[p], FindFront(R[p], x)); return FindFront(L[p], x); } int FindNext(int p, int x){ if(!p) return inf; if(v[p] <= x) return FindNext(R[p], x); return min(v[p], FindNext(L[p], x)); } }treap; int main(){ int T; int op, x; scanf("%d", &T); treap.init(); while(T--){ scanf("%d%d", &op, &x); if(op == 1) treap.Insert(treap.root, x); else if(op == 2) treap.Delete(treap.root, x); else if(op == 3) printf("%d\n", treap.Query_Rank_of_x(treap.root, x)); else if(op == 4) printf("%d\n", treap.Query_kth(treap.root, x)); else if(op == 5) printf("%d\n", treap.FindFront(treap.root, x)); else if(op == 6) printf("%d\n", treap.FindNext(treap.root, x)); } return 0; }