平衡树板子
因为之前写spaly删除出了大锅。。所以就去学了一手fhq-treap。。。
下面是抄来的板子(真香
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
// fhq-treap
const int N = 100005;
int tree[N][2], val[N], size[N], rnd[N], tot;
int p, q, t, root;
void push_up(int x){
size[x] = size[tree[x][0]] + size[tree[x][1]] + 1;
}
int merge(int x, int y){
if(!x || !y) return x + y;
if(rnd[x] < rnd[y]){
tree[x][1] = merge(tree[x][1], y);
push_up(x);
return x;
}
else{
tree[y][0] = merge(x, tree[y][0]);
push_up(y);
return y;
}
}
void split(int cur, int k, int &x, int &y){
if(!cur){ x = 0, y = 0; return; }
if(val[cur] <= k) x = cur, split(tree[cur][1], k, tree[cur][1], y);
else y = cur, split(tree[cur][0], k, x, tree[cur][0]);
push_up(cur);
}
int rndom(){
return rand() << 15 | rand();
}
int newNode(int v){
size[++tot] = 1, rnd[tot] = rndom(), val[tot] = v;
return tot;
}
void insert(int x){
split(root, x, p, q);
root = merge(merge(p, newNode(x)), q);
}
void del(int x){
split(root, x, p, t);
split(p, x - 1, p, q);
q = merge(tree[q][0], tree[q][1]);
root = merge(merge(p, q), t);
}
int select(int cur, int k){
while(1){
if(size[tree[cur][0]] >= k) cur = tree[cur][0];
else{
if(size[tree[cur][0]] + 1 == k) return cur;
else k = k - size[tree[cur][0]] - 1, cur = tree[cur][1];
}
}
}
int ranks(int x){
int ret = 0; split(root, x - 1, p, q);
ret = size[p] + 1;
merge(p, q);
return ret;
}
int successor(int x){
int ret = 0; split(root, x, p, q);
ret = val[select(q, 1)];
root = merge(p, q);
return ret;
}
int precursor(int x){
int ret = 0; split(root, x - 1, p, q);
ret = val[select(p, size[p])];
root = merge(p, q);
return ret;
}
int main(){
srand(time(0));
int n = read();
while(n --){
int opt = read();
if(opt == 1) insert(read());
else if(opt == 2) del(read());
else if(opt == 3) printf("%d
", ranks(read()));
else if(opt == 4) printf("%d
", val[select(root, read())]);
else if(opt == 5) printf("%d
", precursor(read()));
else printf("%d
", successor(read()));
}
return 0;
}