感觉这个玩意就是拆来拆去,所以没啥可学习的
粘一下两个题的代码吧
LGOJ 普通平衡树
#include <bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm {
inline int read() {
int res = 0, f = 1;
char k;
while (!isdigit(k = getchar()))
if (k == '-')
f = -1;
while (isdigit(k)) res = res * 10 + k - '0', k = getchar();
return res * f;
}
const int N = 1e6 + 10, inf = 1e15 + 10;
int base = 12344, tot, rt;
int val[N], ls[N], rs[N], sz[N], rk[N];
inline int random() { return (base *= 102394) %= 239402, base; }
inline int add(int valn) {
sz[++tot] = 1;
ls[tot] = rs[tot] = 0;
val[tot] = valn;
rk[tot] = random();
return tot;
}
inline void update(int rt) {
sz[rt] = sz[ls[rt]] + sz[rs[rt]] + 1;
return;
}
inline void split(int rt, int &a, int &b, int valn) {
if (!rt)
return a = b = 0, void();
if (val[rt] <= valn)
a = rt, split(rs[rt], rs[a], b, valn);
else
b = rt, split(ls[rt], a, ls[b], valn);
return update(rt), void();
}
inline void merge(int &rt, int a, int b) {
if (!b || !a)
return rt = a + b, void();
if (rk[a] < rk[b])
rt = a, merge(rs[rt], rs[a], b);
else
rt = b, merge(ls[rt], a, ls[b]);
return update(rt), void();
}
inline void insert(int &rt, int val) {
int x = 0, y = 0, now = add(val);
split(rt, x, y, val);
merge(x, x, now);
merge(rt, x, y);
return;
}
inline void del(int &rt, int val) {
int x = 0, y = 0, z = 0;
split(rt, x, y, val);
split(x, x, z, val - 1);
merge(z, ls[z], rs[z]);
merge(x, x, z);
merge(rt, x, y);
return;
}
inline int get_kth(int rt, int k) {
while (sz[ls[rt]] + 1 != k) {
if (sz[ls[rt]] >= k)
rt = ls[rt];
else
k -= sz[ls[rt]] + 1, rt = rs[rt];
}
return val[rt];
}
inline int get_rank(int &rt, int val) {
int x = 0, y = 0;
split(rt, x, y, val - 1);
int tmp = sz[x] + 1;
merge(rt, x, y);
return tmp;
}
inline int get_pre(int &rt, int valn) {
int x = 0, y = 0;
split(rt, x, y, valn - 1);
int tmp = get_kth(x, sz[x]);
merge(rt, x, y);
return tmp;
}
inline int get_nxt(int &rt, int valn) {
int x = 0, y = 0;
split(rt, x, y, valn);
int tmp = get_kth(y, 1);
merge(rt, x, y);
return tmp;
}
signed main() {
int n = read();
add(inf);
tot = 1;
sz[1] = 0;
rt = 1;
while (n--) {
int opt = read(), valn = read();
switch (opt) {
case 1:
insert(rt, valn);
break;
case 2:
del(rt, valn);
break;
case 3:
printf("%lld\n", get_rank(rt, valn));
break;
case 4:
printf("%lld\n", get_kth(rt, valn));
break;
case 5:
printf("%lld\n", get_pre(rt, valn));
break;
case 6:
printf("%lld\n", get_nxt(rt, valn));
break;
}
}
return 0;
}
} // namespace yspm
signed main() { return yspm::main(); }
NOI2015 维护数列
#include <bits/stdc++.h>
#define int long long
using namespace std;
namespace yspm{
int st[500005], len;
inline int read() {
int res = 0, f = 1;
char k;
while (!isdigit(k = getchar()))
if (k == '-')
f = -1;
while (isdigit(k)) res = res * 10 + k - '0', k = getchar();
return res * f;
}
struct node {
int l, r, s, val, cov;
bool lz, fl;
int sum, qz, hz, zd;
} t[500005];
int id, rt;
int add(int v) {
id = st[len--];
t[id].l = t[id].r = t[id].lz = t[id].cov = 0;
t[id].s = 1;
t[id].val = t[id].sum = v;
t[id].qz = t[id].hz = max(0ll, v);
t[id].zd = v;
return id;
}
void push_up(int x) {
if (!x)
return;
t[x].s = t[t[x].l].s + t[t[x].r].s + 1;
t[x].sum = t[t[x].l].sum + t[t[x].r].sum + t[x].val;
t[x].qz = max(max(t[t[x].l].qz, t[t[x].l].sum + t[x].val + t[t[x].r].qz), 0ll);
t[x].hz = max(max(t[t[x].r].hz, t[t[x].r].sum + t[x].val + t[t[x].l].hz), 0ll);
t[x].zd = max(t[x].val, t[x].val + t[t[x].l].hz + t[t[x].r].qz);
if (t[x].l)
t[x].zd = max(t[x].zd, t[t[x].l].zd);
if (t[x].r)
t[x].zd = max(t[x].zd, t[t[x].r].zd);
}
void Reverse(int x) {
if (!x)
return;
swap(t[x].l, t[x].r);
swap(t[x].hz, t[x].qz);
t[x].lz ^= 1;
}
void Cover(int x, int ci) {
t[x].val = t[x].cov = ci;
t[x].sum = t[x].s * ci;
t[x].qz = t[x].hz = max(0ll, t[x].sum);
t[x].zd = max(ci, t[x].sum);
t[x].fl = 1;
}
void push_down(int x) {
if (!x)
return;
if (t[x].lz) {
if (t[x].l)
Reverse(t[x].l);
if (t[x].r)
Reverse(t[x].r);
t[x].lz = 0;
}
if (t[x].fl) {
if (t[x].l)
Cover(t[x].l, t[x].cov);
if (t[x].r)
Cover(t[x].r, t[x].cov);
t[x].cov = t[x].fl = 0;
}
}
void del(int x) {
if (!x)
return;
st[++len] = x;
if (t[x].l)
del(t[x].l);
if (t[x].r)
del(t[x].r);
}
void split(int x, int &L, int &R, int K) {
if (x)
push_down(x);
if (!x) {
L = R = 0;
return;
}
if (t[t[x].l].s + 1 <= K)
L = x, split(t[x].r, t[L].r, R, K - t[t[x].l].s - 1);
else
R = x, split(t[x].l, L, t[R].l, K);
push_up(x);
}
void merge(int x, int y, int &root) {
if (!x || !y) {
root = x + y;
return;
}
if (90000008 % (t[x].s + t[y].s) < t[x].s)
push_down(x), root = x, merge(t[x].r, y, t[root].r), push_up(x);
else
push_down(y), root = y, merge(x, t[y].l, t[root].l), push_up(y);
}
int n, m;
int A[500005];
int build(int l, int r) {
if (l == r) {
return add(A[l]);
}
int x, mid = (l + r) >> 1;
merge(build(l, mid), build(mid + 1, r), x);
return x;
}
char opt[10];
signed main() {
n = read(), m = read();
for (int i = 1; i <= 500000; ++i) st[++len] = i;
for (int i = 1; i <= n; ++i) A[i] = read();
merge(rt, build(1, n), rt);
while (m--) {
scanf("%s", opt);
if (opt[0] == 'I') {
int pos = read(), tot = read();
int x, y;
split(rt, x, y, pos);
for (int i = 1; i <= tot; ++i) A[i] = read();
merge(x, build(1, tot), x);
merge(x, y, rt);
} else if (opt[0] == 'D') {
int pos = read(), tot = read();
int x, y, z;
split(rt, x, y, pos - 1);
split(y, y, z, tot);
del(y);
merge(x, z, rt);
} else if (opt[0] == 'M' && opt[2] == 'K') {
int pos = read(), tot = read(), ci = read();
int x, y, z;
split(rt, x, y, pos - 1);
split(y, y, z, tot);
Cover(y, ci);
merge(x, y, x);
merge(x, z, rt);
} else if (opt[0] == 'R') {
int pos = read(), tot = read();
int x, y, z;
split(rt, x, y, pos - 1);
split(y, y, z, tot);
Reverse(y);
merge(x, y, y);
merge(y, z, rt);
} else if (opt[0] == 'G') {
int pos = read(), tot = read();
int x, y, z;
split(rt, x, y, pos - 1);
split(y, y, z, tot);
printf("%d\n", t[y].sum);
merge(x, y, y);
merge(y, z, rt);
} else if (opt[0] == 'M' && opt[2] == 'X') {
printf("%d\n", t[rt].zd);
}
}
return 0;
}
}signed main(){return yspm::main();}