替罪羊树 TLE 96pts 求助
查看原帖
替罪羊树 TLE 96pts 求助
560516
喵仔牛奶楼主2022/12/9 21:53

https://www.luogu.com.cn/record/96930766

#include <bits/stdc++.h>
using namespace std;
const int N = 5e6 + 5;
struct ScapegoatTree {
	const double alpha = 0.666666;
	struct node {
		int val, ls, rs, cnt, tot, siz, tsiz;
	} tree[N];
	int cnt, tot, rt, cur[N];
	bool isBad(int u) {
		return tree[u].cnt && (alpha * tree[u].siz <= double(max(tree[tree[u].ls].siz, tree[tree[u].rs].siz))
			|| double(tree[u].tsiz) < alpha * tree[u].siz);
	}
	void push_up(int u) {
		tree[u].tot = tree[tree[u].ls].tot + tree[tree[u].rs].tot + 1;
		tree[u].siz = tree[tree[u].ls].siz + tree[tree[u].rs].siz + tree[u].cnt;
		tree[u].tsiz = tree[tree[u].ls].tsiz + tree[tree[u].rs].tsiz + bool(tree[u].cnt);
	}
	void dfs(int u) {
		if (!u) return;
		dfs(tree[u].ls);
		if (tree[u].cnt) cur[tot ++] = u;
		dfs(tree[u].rs);
	}
	int build(int l, int r) {
		int mid = (l + r) >> 1;
		if (l >= r) return 0;
		tree[cur[mid]].ls = build(l, mid);
		tree[cur[mid]].rs = build(mid + 1, r);
		push_up(cur[mid]);
		return cur[mid];
	}
	inline void rebuild(int& u) {
		tot = 0, dfs(u);
		if (u == rt) rt = u = build(0, tot);
		else u = build(0, tot);
	}
	int insert(int u, int val) {
		if (!u) {
			u = ++ cnt;
			if (!rt) rt = 1;
			tree[u].val = val;
			tree[u].siz = tree[u].cnt = 1;
		} else {
			if (tree[u].val == val) tree[u].cnt ++;
			if (val < tree[u].val) tree[u].ls = insert(tree[u].ls, val);
			if (val > tree[u].val) tree[u].rs = insert(tree[u].rs, val);
			push_up(u);
			if (isBad(u)) rebuild(u);
		}
		return u;
	}
	void del(int u, int val) {
		if (!u) return;
		if (tree[u].val == val) tree[u].cnt --;
		if (val < tree[u].val) del(tree[u].ls, val);
		if (val > tree[u].val) del(tree[u].rs, val);
		push_up(u);
	}
	int query(int u, int val) {
		if (!u) return 0;
		if (tree[u].val == val) return tree[tree[u].ls].siz;
		if (val < tree[u].val) return query(tree[u].ls, val);
		return query(tree[u].rs, val) + tree[tree[u].ls].siz + tree[u].cnt;
	}
	int Kth(int u, int k) {
		if (!u) return INT_MAX;
		if (tree[tree[u].ls].siz >= k) return Kth(tree[u].ls, k);
		if (tree[tree[u].ls].siz + tree[u].cnt >= k) return tree[u].val;
		return Kth(tree[u].rs, k - tree[tree[u].ls].siz - tree[u].cnt);
	}
	void print(int u) {
		if (!u) return;
		print(tree[u].ls);
		print(tree[u].rs);
		cout << tree[u].val << ' ' << tree[u].cnt << '\n';
	}
} T;
int n, q, opt, u, lastans, ans;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
	cin >> n >> q;
    for (int i = 1; i <= n; i ++)
        cin >> u, T.insert(T.rt, u);
	for (int i = 1; i <= q; i ++) {
		cin >> opt >> u, u ^= lastans;
		if (opt == 1) T.insert(T.rt, u);
		if (opt == 2) T.del(T.rt, u);
		if (opt == 3) ans ^= lastans = T.query(T.rt, u) + 1;
		if (opt == 4) ans ^= lastans = T.Kth(T.rt, u);
		if (opt == 5) ans ^= lastans = T.Kth(T.rt, T.query(T.rt, u));
		if (opt == 6) ans ^= lastans = T.Kth(T.rt, T.query(T.rt, u + 1) + 1);
	}
    cout << ans << '\n';
	return 0;
}

2022/12/9 21:53
加载中...