模板
自己用的可持久化Treap的板子, 改掉split的可持久化就可以当成普通的来用了。
// 使用前插入-INF, 和INF。若不需插入,涉及的排名的地方有加一减一的问题 普通版fhq-treap在split中去掉可持久化就可以。
struct fhq_Treap{
struct {
int val, siz, l, r, rnd;}T[N*60];
int cnt, x, y, z;
void up(int rt) {
T[rt].siz = 1 + T[T[rt].l].siz + T[T[rt].r].siz;
}
int new_node(int x) {
T[++cnt].val = x;
T[cnt].rnd = rand();
T[cnt].siz = 1;
return cnt;
}
void split(int rt, int k, int &x, int &y) {
if(!rt) return x = y = 0, void(0);
if(T[rt].val <= k) {
x = ++cnt; T[x] = T[rt];
split(T[x].r, k, T[x].r, y);
up(x);
} else {
y = ++cnt; T[y] = T[rt];
split(T[y].l, k, x, T[y].l);
up(y);
}
}
int merge(int x, int y) {
if(!x || !y) return x^y;
if(T[x].rnd < T[y].rnd) {
T[x].r = merge(T[x].r, y);
up(x); return x;
}
T[y].l = merge(x, T[y].l);
up(y); return y;
}
void insert(int &rt, int val) {
split(rt, val-1, x, y);
rt = merge(merge(x, new_node(val)), y);
}
void del(int &rt, int val) {
split(rt, val-1, x, y);
split(y, val, z, y);
z = merge(T[z].l, T[z].r);
rt = merge(merge(x, z), y);
}
int _rank(int rt, int val) {
int ans = 0;
while(rt) {
if(val < T[rt].val) rt = T[rt].l;
else if(val == T[rt].val) {
while(T[T[rt].l].val == val) cout << T[rt].val << endl, rt = T[rt].l;
return ans + T[T[rt].l].siz;
}
else ans += T[T[rt].l].siz + 1, rt = T[rt].r;
}
return ans;
}
// 注意k要加1
int _kth(int rt, int k) {
while(rt) {
if(T[T[rt].l].siz >= k) rt = T[rt].l;
else if (T[T[rt].l].siz + 1 == k) return T[rt].val;
else k -= T[T[rt].l].siz + 1, rt = T[rt].r;
}
return INF;
}
int pre(int rt, int val) {
int ans = -INF;
while(rt) {
if(val == T[rt].val) {
if(T[rt].l) {
rt = T[rt].l;
while(T[rt].r) rt = T[rt].r;
ans = T[rt].val;
} break;
}
if(T[rt].val < val && ans < T[rt].val) ans = T[rt].val;
rt = val < T[rt].val ? T[rt].l : T[rt].r;
}
return ans;
}
int nxt(int rt, int val) {
int ans = INF;
while(rt) {
if(val == T[rt].val) {
if(T[rt].r) {
rt = T[rt].r;
while(T[rt].l) rt = T[rt].l;
ans = T[rt].val;
} break;
}
if(T[rt].val > val && ans > T[rt].val) ans = T[rt].val;
rt = val > T[rt].val ? T[rt].r : T[rt].l;
}
return ans;
}
}Tr;
P6136 【模板】普通平衡树(数据加强版)
普通平衡树
其实对于非删除插入操作都可以迭代求答案,不调用split。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
namespace {
template <typename T> inline void read(T &x) {
x = 0; T f = 1;char s = getchar();
for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
for(; isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
x *= f;
}
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define _srep(n,m,i)for (register int i = (n); i >= (m); i--)
#define _sfor(n,m,i)for (register int i = (n); i > (m); i--)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair<int,int>
#define fi first
#define se second
const int N = 2e6+5;
int val[N], ch[N][2], siz[N], rnd[N], q[N];
int root, cnt, x, y, z, an, tot;
void up(int rt) {
siz[rt] = 1 + siz[ch[rt][0]] + siz[ch[rt][1]];
}
int new_node(int x) {
int new_cnt = tot ? q[tot--] : ++cnt;
val[new_cnt] = x;
siz[new_cnt] =</