# BZOJ3600 没有人的算术（替罪羊树，线段树）

## 解题思路

const int N = 100059;
const int M = 500909;
int V[M], cnt;
struct node {
int ls, rs;
node (int l = 0, int r = 0) : ls(l), rs(r) {}
bool operator < (const node &i) const {
return ls != i.ls ? V[ls] < V[i.ls] : V[rs] < V[i.rs];
}
bool operator == (const node &i) const { return ls == i.ls && rs == i.rs; }
}val[M];

#define ls p << 1
#define rs ls | 1
int id[N], mx[N<<2], rt, m, n;
void build(int p, int l, int r) {
mx[p] = l; if (l == r) return ;
int mid = (l + r) >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
}

inline bool cmp(int x, int y) { return V[id[x]] >= V[id[y]]; }
void change(int p, int l, int r, int x) {
if (l == r) return mx[p] = l, void();
int mid = (l + r) >> 1;
x <= mid ? change(ls, l, mid, x) : change(rs, mid + 1, r, x);
mx[p] = cmp(mx[ls], mx[rs]) ? mx[ls] : mx[rs];
}

int query(int p, int l, int r, int L, int R) {
if (L <= l && r <= R) return mx[p];
int mid = (l + r) >> 1, res = 0;
if (L <= mid) res = query(ls, l, mid, L, R);
if (R > mid) {
int t = query(rs, mid + 1, r, L, R);
if (!cmp(res, t)) res = t;
}
return res;
}

namespace SCT {
#undef ls
#undef rs
int st[M], siz[M], ls[M], rs[M], tp;
void pia(int x) { if (ls[x]) pia(ls[x]); st[++tp] = x; if (rs[x]) pia(rs[x]); }
int build(int l, int r, int L, int R) {
int mid = (l + r) >> 1, x = st[mid];
int m2 = V[x] = (L + R) >> 1;
ls[x] = l < mid ? build(l, mid - 1, L, m2 - 1) : 0;
rs[x] = r > mid ? build(mid + 1, r, m2 + 1, R) : 0;
if (l == r) return siz[st[l]] = 1, st[l];
return siz[x] = siz[ls[x]] + siz[rs[x]], x;
}
void rebuild(int &p, int L, int R) { tp = 0, pia(p), p = build(1, tp, L, R); }
int insert(int &p, int l, int r, node t) {
if (!p) { val[p = ++cnt] = t, V[p] = (l + r) >> 1; siz[p] = 1; return p; }
int mid = (l + r) >> 1, res = 0;
if (t == val[p]) return p;
if (t < val[p]) res = insert(ls[p], l, mid - 1, t);
else res = insert(rs[p], mid + 1, r, t);
siz[p] = siz[ls[p]] + siz[rs[p]] + 1;
if (max(siz[ls[p]], siz[rs[p]]) >= siz[p] * 0.73) rebuild(p, l, r);
return res;
}
}

char op[5];
int main() {
read(n), read(m); V[0] = val[0].ls = -1, SCT::insert(rt, 1, 1e9, node(0, 0));
for (int i = 1;i <= n; ++i) id[i] = 1; build(1, 1, n);
for (int i = 1, l, r, k;i <= m; ++i) {
if (op[0] == 'C') {
read(k), id[k] = SCT::insert(rt, 1, 1e9, node(id[l], id[r]));
change(1, 1, n, k);
} else write(query(1, 1, n, l, r));
}
return 0;
}

/*

5 10
C 1 1 1
C 2 1 2
Q 1 2
C 4 4 4
C 5 5 5
Q 4 5
Q 3 3
C 4 2 3
C 4 4 4
Q 3 4

*/

posted @ 2021-01-29 19:18  Hs-black  阅读(120)  评论(0编辑  收藏  举报