树剖求调
查看原帖
树剖求调
543078
songziyu楼主2024/11/20 21:57

不过样例。。。
(由于个人马蜂显得较长)

#include <bits/stdc++.h>
#define int long long
#define ls p<<1
#define rs p<<1|1
using namespace std;
const int N = 1e5 + 5;
int mod = 1e18 + 3, inf = 2e18;
int root = 1;
int f[N], dep[N], siz[N], son[N];
int top[N], dfn[N], rnk[N], tot;
int n, q, ecnt, last[N], a[N];
struct edge
{
	int to, pre;
} e[N << 1];
struct Node
{
	int l, r, w;
	int tag3;
} t[N << 2];
void addedge(int u, int v)
{
	e[++ecnt].to = v, e[ecnt].pre = last[u], last[u] = ecnt;
}
void push_up(int p)
{
	t[p].w = (t[ls].w + t[rs].w);
}
void build(int p, int l, int r)
{
	t[p].l = l, t[p].r = r;
	t[p].tag3 = -inf;
	if (l == r)
	{
		t[p].w = rnk[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	push_up(p);
}
void push_down(int p)
{
	if (t[p].tag3 != -inf)
	{
		t[ls].w = t[p].tag3 * (t[ls].r - t[ls].l + 1);
		t[rs].w = t[p].tag3 * (t[rs].r - t[rs].l + 1);
		t[ls].tag3 = t[p].tag3;
		t[rs].tag3 = t[p].tag3;
		t[p].tag3 = -inf;
	}
}
int ask(int p, int l, int r)
{
	if (l <= t[p].l && r >= t[p].r)
	{
		return t[p].w;
	}
	push_down(p);
	int mid = (t[p].l + t[p].r) >> 1, ans = 0;
	if (l <= mid)
	{
		ans = (ans + ask(ls, l, r));
	}
	if (r > mid)
	{
		ans = (ans + ask(rs, l, r));
	}
	return ans;
}
void modify(int p, int l, int r, int k)
{
	if (l <= t[p].l && r >= t[p].r)
	{
		t[p].w = k * (t[p].r - t[p].l + 1);
		t[p].tag3 = k;
		return;
	}
	push_down(p);
	int mid = (t[p].l + t[p].r) >> 1;
	if (l <= mid)
	{
		modify(ls, l, r, k);
	}
	if (r > mid)
	{
		modify(rs, l, r, k);
	}
	push_up(p);
}
void dfs1(int u, int fa)
{
	f[u] = fa, dep[u] = dep[fa] + 1, siz[u] = 1;
	for (int i = last[u]; i; i = e[i].pre)
	{
		int v = e[i].to;
		if (v == fa)
		{
			continue;
		}
		dfs1(v, u);
		siz[u] += siz[v];
		if (siz[son[u]] < siz[v])
		{
			son[u] = v;
		}
	}
}
void dfs2(int u, int t)
{
	dfn[u] = ++tot;
	rnk[tot] = a[u];
	top[u] = t;
	if (son[u])
	{
		dfs2(son[u], t);
	}
	for (int i = last[u]; i; i = e[i].pre)
	{
		int v = e[i].to;
		if (v == f[u] || v == son[u])
		{
			continue;
		}
		dfs2(v, v);
	}
}
int sum_path(int x, int y)
{
	int ans = 0;
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
		{
			swap(x, y);
		}
		ans = (ans + ask(1, dfn[top[x]], dfn[x]));
		x = f[top[x]];
	}
	if (dep[x] < dep[y])
	{
		swap(x, y);
	}
	ans = (ans + ask(1, dfn[y], dfn[x]));
	return ans;
}
void modify_path(int x, int y, int k)
{
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
		{
			swap(x, y);
		}
		modify(1, dfn[top[x]], dfn[x], k);
		x = f[top[x]];
	}
	if (dep[x] < dep[y])
	{
		swap(x, y);
	}
	modify(1, dfn[y], dfn[x], k);
}
void modify_tree(int x, int k)
{
	modify(1, dfn[x], dfn[x] + siz[x] - 1, k);
}
int sum_tree(int x)
{
	return ask(1, dfn[x], dfn[x] + siz[x] - 1);
}
signed main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++)
	{
		int u;
		cin >> u;
		addedge(++u, i), addedge(i, u);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	cin >> q;
	for (int i = 1; i <= q; i++)
	{
		string op;
		int x;
		cin >> op >> x;
		x++;
		if (op == "install")
		{
			cout << sum_path(1, x) << '\n';
			modify_path(1, x, 0);
		}
		else
		{
			cout << siz[x] - sum_tree(x) << '\n';
			modify_tree(x, 1);
		}
	}
	return 0;
}
2024/11/20 21:57
加载中...