洛谷 P2343 宝石管理系统
Description
Solution
无旋treap \((fhq-treap)\)
洛谷模板题简化版。
不多说了。
有不会的话看我的博客吧。
有一个小坑点,题目中求的是第 \(n\) 大的数是多少,所以查询时要查 \(tot - n + 1\) (\(tot\) 是总结点数)。
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#define ls(x) t[x].ch[0]
#define rs(x) t[x].ch[1]
using namespace std;
const int N = 2e5 + 10;
struct Tree{
int ch[2], val, siz, wei;
}t[N];
int n, m, tot, root;
int a, b, c;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
inline void pushup(int x){
t[x].siz = t[ls(x)].siz + t[rs(x)].siz + 1;
}
inline void split(int x, int k, int &a, int &b){
if(!x){
a = b = 0;
return;
}
if(t[x].val <= k){
a = x;
split(rs(x), k, rs(x), b);
}else{
b = x;
split(ls(x), k, a, ls(x));
}
pushup(x);
}
inline int merge(int x, int y){
if(!x || !y) return x + y;
if(t[x].wei <= t[y].wei){
rs(x) = merge(rs(x), y);
pushup(x);
return x;
}else{
ls(y) = merge(x, ls(y));
pushup(y);
return y;
}
}
inline void insert(int k){
t[++tot].val = k, t[tot].siz = 1, t[tot].wei = rand();
split(root, k, a, b);
root = merge(merge(a, tot), b);
}
inline int check_val(int x, int k){
if(k == t[ls(x)].siz + 1) return t[x].val;
if(k <= t[ls(x)].siz) return check_val(ls(x), k);
else return check_val(rs(x), k - t[ls(x)].siz - 1);
}
int main(){
n = read(), m = read();
for(int i = 1; i <= n; i++){
int x = read();
insert(x);
}
for(int i = 1; i <= m; i++){
int op = read(), x = read();
if(op == 1) printf("%d\n", check_val(root, tot - x + 1));
else insert(x);
}
return 0;
}