树链剖分 0 pts 求助
查看原帖
树链剖分 0 pts 求助
688783
SilverLi楼主2023/7/13 11:46
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
const int M = 4e5 + 5;
int n, q;
vector<int> g[N];
int dex;
int fa[N], son[N], si[N];
int d[N], top[N], dfn[N];
int cnt, t[M], ad[M];
#define mid (l + r >> 1)
#define len (r - l + 1)
inline void down(int p, int l, int r) {
	if (ad[p] != -1) {
		t[p << 1] = ad[p] * (len >> 1);
		t[p << 1 | 1] = ad[p] * (len - (len >> 1));
		ad[p << 1] = ad[p << 1 | 1] = ad[p];
		ad[p] = -1;
	}
}
void cover(int l, int r, int S, int T, int p, int w) {
	if (l >= S && r <= T) {
		t[p] = len * w;
		ad[p] = w;
		return;
	}
	down(p, l, r);
	if (S <= mid)
		cover(l, mid, S, T, p << 1, w);
	if (T > mid)
		cover(mid + 1, r, S, T, p << 1 | 1, w);
	t[p] = t[p << 1] + t[p << 1 | 1];
}
int ask(int l, int r, int S, int T, int p) {
	if (l >= S && r <= T)
		return t[p];
	down(p, l, r);
	int sum = 0;
	if (S <= mid)
		sum += ask(l, mid, S, T, p << 1);
	if (T > mid)
		sum += ask(mid + 1, r, S, T, p << 1 | 1);
	return sum;
}
void dfs(int u, int ft) {
	d[u] = d[ft] + 1;
	fa[u] = ft, si[u] = 1;
	for (int l = 0; l < g[u].size(); ++l) {
		int i = g[u][l];
		if (i != ft) {
			dfs(i, u);
			si[u] += si[i];
			if (si[son[u]] < si[i])
				son[u] = i;
		}
	}
}
void dfs2(int u, int deep) {
	dfn[u] = ++dex;
	top[u] = deep;
	if (!son[u])	return;
	dfs2(son[u], deep);
	for (int l = 0; l < g[u].size(); ++l) {
		int i = g[u][l];
		if (i != fa[u] && i != son[u])
			dfs2(i, i);
	}
}
inline void LCA(int u, int v) {
	while (top[u] != top[v]) {
		if (d[top[u]] < d[top[v]])  swap(u, v);
		cover(1, n, dfn[top[u]], dfn[u], 1, 1);
		u = fa[top[u]];
	}
	if (d[u] > d[v])    swap(u, v);
	cover(1, n, dfn[u], dfn[v], 1, 1);
}
signed main() {
	cin >> n;
	for (int u = 2; u <= n; ++u) {
		int v;
		cin >> v;
		++v;//start 0
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(1, 0);
	dfs2(1, 1);
	memset(ad, -1, sizeof(ad));
	cin >> q;
	while (q--) {
		int x;
		string opt;
		cin >> opt >> x;
		++x;
		int last = t[1];
		if (opt[0] == 'i')
			LCA(1, x);
		else
			cover(1, n, dfn[x], dfn[x] + si[x] - 1, 1, 0);
		int now = t[1];
		cout << abs(now - last) << '\n';
	}
	return 0;
}

2023/7/13 11:46
加载中...