洛谷 P3380 模板 二逼平衡树 线段树套平衡树
Code
#include <cstdio>
#include <cstdlib>
using namespace std;
const int N = 1800010, INF = 1000000000;
struct Treap {
int l[N], r[N], d[N], siz[N], cnt[N], val[N];
int tot, rt, ERR;
int mk(int v) {
val[++tot] = v;
d[tot] = rand();
siz[tot] = 1;
cnt[tot] = 1;
return tot;
}
int update(int x) {
return siz[x] = siz[l[x]] + siz[r[x]] + cnt[x];
}
int leftRotate(int &x) {
int tmp = r[x];
r[x] = l[tmp];
l[tmp] = x;
x = tmp;
update(l[x]);
update(x);
return x;
}
int rightRotate(int &x) {
int tmp = l[x];
l[x] = r[tmp];
r[tmp] = x;
x = tmp;
update(r[x]);
update(x);
return x;
}
void insert(int &x, int v) {
if (!x) {
x = mk(v);
return ;
}
if (v == val[x]) ++cnt[x];
else {
if (v < val[x]) {
insert(l[x], v);
if (d[x] < d[l[x]])
rightRotate(x);
} else {
insert(r[x], v);
if (d[x] < d[r[x]])
leftRotate(x);
}
}
update(x);
return ;
}
void erase(int &x, int v) {
if (!x) return ;
if (v == val[x]) {
if (cnt[x] > 1) --cnt[x], update(x);
else if (!l[x] && !r[x]) x = 0;
else {
if (!r[x] || d[r[x]] < d[l[x]]) rightRotate(x), erase(r[x], v);
else leftRotate(x), erase(l[x], v);
update(x);
}
return ;
}
if (v < val[x]) erase(l[x], v);
else erase(r[x], v);
update(x);
return ;
}
void del(int &x, int v) {
if (!x) return ;
if (v == val[x]) {
cnt[x] = 1, update(x);
if (!l[x] && !r[x]) x = 0;
else {
if (!r[x] || d[r[x]] < d[l[x]]) rightRotate(x), del(r[x], v);
else leftRotate(x), del(l[x], v);
update(x);
}
return ;
}
if (v < val[x]) del(l[x], v);
else del(r[x], v);
update(x);
return ;
}
int rank(int rt, int v) {
int x, ans = 0;
for (x = rt; x;) {
if (v < val[x]) x = l[x];
else if (v > val[x]) ans += siz[l[x]] + cnt[x], x = r[x];
else return ans + siz[l[x]] + 1;
}
return ans + 1;
}
int value(int rt, int v) {
int x;
for (x = rt; x;) {
if (v <= siz[l[x]]) x = l[x];
else if (v <= siz[l[x]] + cnt[x]) return val[x];
else v -= siz[l[x]] + cnt[x], x = r[x];
}
return ERR;
}
bool find(int rt, int v) {
int x;
for (x = rt; x;) {
if (v < val[x]) x = l[x];
else if (v > val[x]) x = r[x];
else return 1;
}
return 0;
}
int count(int rt, int v) {
int x;
for (x = rt; x;) {
if (v < val[x]) x = l[x];
else if (v > val[x]) x = r[x];
else return cnt[x];
}
return ERR;
}
int pre(int rt, int v) {
int res = ERR;
for (int x = rt; x;)
if (val[x] < v) res = val[x], x = r[x];
else x = l[x];
return res;
}
int nxt(int rt, int v) {
int res = ERR;
for (int x = rt; x;)
if (val[x] > v) res = val[x], x = l[x];
else x = r[x];
return res;
}
int max(int rt) {
int x;
for (x = rt; r[x]; x = r[x]);
return val[x];
}
int min(int rt) {
int x;
for (x = rt; l[x]; x = l[x]);
return val[x];
}
int clear(int error) {
rt = tot = 0;
return ERR = error;
}
int error() {
return ERR;
}
void insert(int x) {
insert(rt, x);
return ;
}
void erase(int x) {
erase(rt, x);
return ;
}
void del(int x) {
del(rt, x);
return ;
}
int rank(int v) {
return rank(rt, v);
}
int value(int v) {
return value(rt, v);
}
bool find(int v) {
return find(rt, v);
}
int count(int v) {
return count(rt, v);
}
int pre(int v) {
return pre(rt, v);
}
int nxt(int v) {
return nxt(rt, v);
}
int max() {
return max(rt);
}
int min() {
int x;
for (x = rt; l[x]; x = l[x]);
return min(rt);
}
int size(int rt) {
return siz[rt];
}
bool empty(int rt) {
return !siz[rt];
}
int size() {
return siz[rt];
}
bool empty() {
return !siz[rt];
}
} ;
struct Segment {
int rt[N], n, err, mn, mx;
int* s;
Treap t;
int min(int x, int y) {
return x < y ? x : y;
}
int max(int x, int y) {
return x > y ? x : y;
}
void build(int k, int l, int r) {
rt[k] = 0;
for (int i = l; i <= r; ++i)
t.insert(rt[k], s[i]);
if (l < r) {
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
}
return ;
}
int rank(int k, int l, int r, int x, int y, int v) {
if (x <= l && r <= y)
return t.rank(rt[k], v) - 1;
int mid = (l + r) >> 1, res = 0;
if (x <= mid)
res += rank(k << 1, l, mid, x, y, v);
if (y > mid)
res += rank(k << 1 | 1, mid + 1, r, x, y, v);
return res;
}
int value(int l, int r, int v) {
int el, er, mid;
for (el = mn, er = mx; el < er;) {
mid = (el + er + 1) >> 1;
if (rank(1, 1, n, l, r, mid) < v)
el = mid;
else
er = mid - 1;
}
return el;
}
void modify(int k, int l, int r, int x, int v) {
t.erase(rt[k], s[x]);
t.insert(rt[k], v);
mn = min(mn, v);
mx = max(mx, v);
if (l == r)
return;
int mid = (l + r) >> 1;
if (x <= mid)
modify(k << 1, l, mid, x, v);
if (x > mid)
modify(k << 1 | 1, mid + 1, r, x, v);
return ;
}
int pre(int k, int l, int r, int x, int y, int v) {
if (x <= l && r <= y)
return t.pre(rt[k], v);
int mid = (l + r) >> 1, ans = mn - 1;
if (x <= mid) {
int res = pre(k << 1, l, mid, x, y, v);
if (res != err)
ans = max(ans, res);
}
if (y > mid) {
int res = pre(k << 1 | 1, mid + 1, r, x, y, v);
if (res != err)
ans = max(ans, res);
}
if (ans == mn - 1)
return err;
return ans;
}
int nxt(int k, int l, int r, int x, int y, int v) {
if (x <= l && r <= y)
return t.nxt(rt[k], v);
int mid = (l + r) >> 1, ans = mx + 1;
if (x <= mid) {
int res = nxt(k << 1, l, mid, x, y, v);
if (res != err)
ans = min(ans, res);
}
if (y > mid) {
int res = nxt(k << 1 | 1, mid + 1, r, x, y, v);
if (res != err)
ans = min(ans, res);
}
if (ans == mx + 1)
return err;
return ans;
}
void build(int n, int inf, int error, int* s) {
mn = inf;
mx = -inf;
this->n = n;
this->s = s;
this->err = error;
for (int i = 1; i <= n; ++i) {
mn = min(mn, s[i]);
mx = max(mx, s[i]);
}
t.clear(error);
build(1, 1, n);
return ;
}
int rank(int l, int r, int v) {
return rank(1, 1, n, l, r, v) + 1;
}
void modify(int x, int v) {
modify(1, 1, n, x, v);
s[x] = v;
return ;
}
int pre(int x, int y, int v) {
return pre(1, 1, n, x, y, v);
}
int nxt(int x, int y, int v) {
return nxt(1, 1, n, x, y, v);
}
} ;
Segment tr;
int s[N];
int main() {
int n, q, opt, l, r, v;
scanf("%d %d", &n, &q);
for (int i = 1; i <= n; ++i)
scanf("%d", &s[i]);
tr.build(n, INF, -1, s);
for (; q; --q) {
scanf("%d %d %d", &opt, &l, &r);
if (opt == 3)
tr.modify(l, r);
else {
scanf("%d", &v);
if (opt == 1) printf("%d\n", tr.rank(l, r, v));
else if (opt == 2) printf("%d\n", tr.value(l, r, v));
else if (opt == 4) {
int res = tr.pre(l, r, v);
printf("%d\n", res == -1 ? -2147483647 : res);
} else {
int res = tr.nxt(l, r, v);
printf("%d\n", res == -1 ? 2147483647 : res);
}
}
}
return 0;
}