不会线段树的萌新求卡常
查看原帖
不会线段树的萌新求卡常
560516
喵仔牛奶楼主2022/8/22 10:20

rt,不开 O2 过不去。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
struct edge {
	int v, next;
} e[N << 1];
int a[N], w[N], pos[N], sum[N], L[N], R[N], tag[N], head[N], fa[N], id[N], siz[N], top[N], depth[N], son[N];
int edge_cnt, n, q, u, v, x, cnt, awa, slen, sum1, sum2;
char opt[10];
inline void build() {
	memset(tag, -1, sizeof tag);
	slen = sqrt(n), awa = n / slen + (n % slen != 0);
	for (int id = 1; id <= awa; id ++)
		L[id] = (id - 1) * slen + 1, R[id] = id * slen;
	R[awa] = n;
	for (int id = 1; id <= awa; id ++)
		for (int j = L[id]; j <= R[id]; j ++)
			pos[j] = id, sum[id] += a[j];
}
inline void rebuild(int id) {
    sum[id] = 0;
    for (int i = L[id]; i <= R[id]; i ++)
    	sum[id] += a[i];
}
inline void pushdown(int id) {
	if (!~tag[id]) return;
	for (int i = L[id]; i <= R[id]; i ++)
		a[i] = tag[id];
	tag[id] = -1;
}
inline void change(int l, int r, int x) {
	int lp = pos[l], rp = pos[r];
	pushdown(lp), pushdown(rp);
	if (lp == rp) {
		for (int i = l; i <= r; i ++) a[i] = x;
		return rebuild(lp);
	}
	for (int i = l; i <= R[lp]; i ++) a[i] = x;
	for (int id = lp + 1; id < rp; id ++) tag[id] = x, sum[id] = slen * x;
	for (int i = L[rp]; i <= r; i ++) a[i] = x;
	rebuild(lp), rebuild(rp);
}
inline int query(int l, int r) {
	int lp = pos[l], rp = pos[r], ans = 0;
	pushdown(lp), pushdown(rp);
	rebuild(lp), rebuild(rp);
	if (lp == rp) {
		for (int i = l; i <= r; i ++)
			ans += a[i];
		return ans;
	}
	for (int i = l; i <= R[lp]; i ++) ans += a[i];
	for (int i = lp + 1; i < rp; i ++) ans += sum[i];
	for (int i = L[rp]; i <= r; i ++) ans += a[i]; 
	return ans;
}
void dfs1(int u, int f, int dep) {
	fa[u] = f, siz[u] = 1, depth[u] = dep;
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].v;
		if (v == f) continue;
		dfs1(v, u, dep + 1);
		if (siz[v] > siz[son[u]])
			son[u] = v;
		siz[u] += siz[v];
	}
}
void dfs2(int u, int topf) {
	id[u] = ++ cnt, a[cnt] = w[u], top[u] = topf;
	if (!son[u]) return;
	dfs2(son[u], topf);
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].v;
		if (v == son[u] || v == fa[u]) continue;
		dfs2(v, v);
	}
}
inline int qRange(int u, int v) {
	int ans = 0;
	while (top[u] != top[v]) {
		if (depth[top[u]] < depth[top[v]]) swap(u, v);
		ans += query(id[top[u]], id[u]), u = fa[top[u]];
	}
	if (depth[u] > depth[v]) swap(u, v);
	return ans + query(id[u], id[v]);
}
inline void updRange(int u, int v, int x) {
	while (top[u] != top[v]) {
		if (depth[top[u]] < depth[top[v]]) swap(u, v);
		change(id[top[u]], id[u], x), u = fa[top[u]];
	}
	if (depth[u] > depth[v]) swap(u, v);
	change(id[u], id[v], x);
}
inline int qTree(int u) {
	return query(id[u], id[u] + siz[u] - 1);
}
inline void updTree(int u, int x) {
	change(id[u], id[u] + siz[u] - 1, x);
}
inline void add(int u, int v) {
	e[++ edge_cnt].v = v;
	e[edge_cnt].next = head[u];
	head[u] = edge_cnt;
}
inline int read() {
	register int t = 1, a = 0;
	register char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') t = -1;
		ch = getchar();
	}
	while (ch <= '9' && ch >= '0')
		a = a * 10 + ch - '0', ch = getchar();
	return a * t;
}
int main() {
	n = read();
	for (int i = 1; i < n; i ++)
		add(read() + 1, i + 1);
	q = read(), dfs1(1, 0, 1), dfs2(1, 1), build();
	for (int i = 1; i <= q; i ++) {
		scanf("%s", opt), u = read() + 1;
		if (opt[0] == 'i') sum1 = qRange(1, u), updRange(1, u, 1), sum2 = qRange(1, u);
		else sum1 = qTree(u), updTree(u, 0), sum2 = qTree(u);
		printf("%d\n", abs(sum1 - sum2));
	}
	return 0;
}
2022/8/22 10:20
加载中...