做題記錄 Luogu P2343
阿新 • • 發佈:2021-06-17
平衡樹水題
比 treap 模板還要弱
#include<bits/stdc++.h> using namespace std; #define maxn 80005 * 50 class fhqtreap { private: long long ch[maxn][2], size[maxn], rnd[maxn], val[maxn], tot; public: long long cnt, root; void pushup(long long x) { size[x] = size[ch[x][0]] + size[ch[x][1]] + 1; return; } long long newnode(long long v) { long long x = ++tot; ch[x][0] = 0; ch[x][1] = 0; val[x] = v; size[x] = 1; rnd[x] = rand() % 500000; return x; } void give(long long a, long long b) { ch[a][0] = ch[b][0]; ch[a][1] = ch[b][1]; size[a] = size[b]; rnd[a] = rnd[b]; val[a] = val[b]; return; } long long merge(long long a, long long b) { if(!a || !b) { return a + b; } if(rnd[a] < rnd[b]) { ch[a][1] = merge(ch[a][1], b); pushup(a); return a; } else { ch[b][0] = merge(a, ch[b][0]); pushup(b); return b; } } void split(long long rt, long long v, long long &x, long long &y) { if(!rt) { x = 0; y = 0; return; } if(val[rt] <= v) { x = rt; split(ch[rt][1], v, ch[rt][1], y); pushup(x); } else { y = rt; split(ch[rt][0], v, x, ch[rt][0]); pushup(y); } return; } void del(long long &rt, long long v) { long long x = 0, y = 0, z = 0; split(rt, v, x, z); split(x, v - 1, x, y); y = merge(ch[y][0], ch[y][1]); rt = merge(merge(x, y), z); return; } void insert(long long &rt, long long v) { long long x = 0, y = 0, z = 0; split(rt, v, x, y); z = newnode(v); rt = merge(merge(x, z), y); return; } long long kth(long long rt, long long k) { while(rt) { //cout << rt << ":" << val[rt] << ":" << k << endl; if(size[ch[rt][1]] + 1 == k) { return val[rt]; } if(k <= size[ch[rt][1]]) { rt = ch[rt][1]; } else { k = k - size[ch[rt][1]] - 1; rt = ch[rt][0]; } } } long long rank(long long &rt, long long v) { long long x = 0, y = 0; split(rt, v - 1, x, y); long long ret = size[x] + 1; rt = merge(x, y); return ret; } long long pre(long long &rt, long long v) { long long x = 0, y = 0, z = 0; split(rt, v - 1, x, y); long long k = size[x]; if(k == 0) { return -1; } split(y, v, y, z); if(size[y] > 1) { rt = merge(merge(x, y), z); return val[y]; } long long ret = kth(x, k); rt = merge(merge(x, y), z); return ret; } long long succ(long long &rt, long long v) { long long x = 0, y = 0, z = 0; split(rt, v, x, y); if(size[y] == 0) { return -1; } split(x, v - 1, x, z); if(size[z] > 1) { rt = merge(merge(x, z), y); return val[z]; } long long ret = kth(y, 1); rt = merge(merge(x, z), y); return ret; } }; fhqtreap stone; int main() { //ios::sync_with_stdio(false); //cin.tie(0); //cout.tie(0); long long n, q, opt, x, ans = 0, sum, num1, num2, flag; cin >> n >> q; for(int i = 1; i <= n; i++) { cin >> x; stone.insert(stone.root, x); } for(long long i = 1; i <= q; i++) { cin >> opt >> x; if(opt == 1) { cout << stone.kth(stone.root, x) << endl; } else { stone.insert(stone.root, x); } } return 0; }