普通的Treap模板
今天自己实现成功
/* * @Author: chenkexing * @Date: 2019-08-02 20:30:39 * @Last Modified by: chenkexing * @Last Modified time: 2019-08-02 22:33:17 */ // #pragma GCC optimize(2) // #pragma GCC optimize(3) // #pragma GCC optimize(4) #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <stack> #include <cmath> #include <queue> #include <list> #include <map> #include <set> #include <cassert> // #include<bits/extc++.h> // using namespace __gnu_pbds; using namespace std; #define pb push_back #define fi first #define se second #define debug(x) cerr<<#x << " := " << x << endl; #define bug cerr<<"-----------------------"<<endl; #define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; template<typename T> inline T read(T&x){ x=0;int f=0;char ch=getchar(); while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x=f?-x:x; } /**********showtime************/ struct Node{ Node * ch[2]; int r; int v; int s; int cnt; Node(int val = 0){ ch[0] = ch[1] = NULL; v = val; r = rand(); s = 1; cnt = 1; } int cmp(int x) const{ if(x == v) return -1; return x < v ? 0 : 1; } void maintain(){ s = cnt; if(ch[0] != NULL) s+=ch[0]->s; if(ch[1] != NULL) s+=ch[1]->s; } }*rt; void rotate(Node* &o, int d) { Node* k = o->ch[d^1]; o ->ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o; o->maintain(); k->maintain(); o = k; } void insert(Node* &o, int x) { if(o == NULL) {o = new Node(x);} else if(o->v == x) {o->cnt++;} else { int d = o->cmp(x); insert(o->ch[d], x); if(o->ch[d] -> r > o->r) rotate(o, d^1); } o->maintain(); } void remove(Node* &o, int x) { int d = o->cmp(x); if(d == -1) { if(o->cnt > 1) o->cnt --; else if(o->ch[0] == NULL) o = o->ch[1]; else if(o->ch[1] == NULL) o = o->ch[0]; else { int d2 = (o->ch[0] -> r > o->ch[1] -> r ? 1 : 0); rotate(o, d2); remove(o->ch[d2], x); } } else remove(o->ch[d], x); if(o != NULL) o->maintain(); } int find(Node* o, int x) { while(o != NULL) { int d = o->cmp(x); if(d == -1) return o->cnt; else o = o->ch[d]; } return 0; } //返回第k小的数,不存在返回-inf int kth(Node* o, int k){ if(o == NULL || k <= 0 || k > o->s) return -inf; int s = (o->ch[0] == NULL ? 0 : o->ch[0]->s); if(s + 1 <= k && s + o->cnt >= k) return o->v; else if(s >= k) return kth(o->ch[0], k); else return kth(o->ch[1], k - s - o->cnt); } //返回比x值小的个数 int rannk(Node* o, int x) { if(o == NULL) return 0; int s = (o->ch[0] == NULL ? 0 : o->ch[0]->s); if(o->v == x) return rannk(o->ch[0], x); else if(o->v > x)return rannk(o->ch[0], x); else return s + o->cnt + rannk(o->ch[1], x); } //合并两个Treap void mergeto(Node* &src, Node* &dest) { if(src->ch[0] != NULL) mergeto(src->ch[0], dest); if(src->ch[1] != NULL) mergeto(src->ch[1], dest); insert(dest, src->v); delete src; src = NULL; } //清空树 void removetree(Node* &x) { if(x->ch[0] != NULL) removetree(x->ch[0]); if(x->ch[1] != NULL) removetree(x->ch[1]); delete x; x = NULL; } int main(){ srand(time(0)); int m; scanf("%d", &m); while(m --) { int op,x; scanf("%d%d", &op, &x); if(op == 1) insert(rt, x); else if(op == 2) remove(rt, x); else if(op == 3) printf("%d\n", rannk(rt, x) + 1); else if(op == 4) printf("%d\n", kth(rt, x)); else if(op == 5) { int k = rannk(rt, x); printf("%d\n", kth(rt, k)); } else { int k = rannk(rt, x); k += find(rt, x); printf("%d\n", kth(rt, k+1)); } } return 0; }