只过了 Hack 求调
查看原帖
只过了 Hack 求调
549357
幸存者楼主2023/8/15 12:35
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, a[100010], sum[400010], al[400010], ar[400010], lazy[400010];
int cnt, fa[100010], dep[100010], siz[100010], son[100010], top[100010], dfn[100010], rnk[100010];
vector<int> v[100010];
void dfs1(int x, int f)
{
	siz[x] = 1;
	for (auto i : v[x])
	{
		if (i == f) continue;
		fa[i] = x, dep[i] = dep[x] + 1;
		dfs1(i, x);
		siz[x] += siz[i];
		if (siz[i] > siz[son[x]]) son[x] = i;
	}
}
void dfs2(int x, int f)
{
	top[x] = f, dfn[x] = ++cnt, rnk[cnt] = x;
	if (!son[x]) return;
	dfs2(son[x], f);
	for (auto i : v[x])
	{
		if (fa[x] == i || son[x] == i) continue;
		dfs2(i, i);
	}
}
void maketag(int u, int x)
{
	sum[u] = 1, al[u] = ar[u] = lazy[u] = x;
}
void pushdown(int u, int L, int R)
{
	int M = L + R >> 1;
	if (lazy[u]) maketag(u << 1, lazy[u]);
	if (lazy[u]) maketag(u << 1 | 1, lazy[u]);
	lazy[u] = 0;
}
void pushup(int u)
{
	sum[u] = sum[u << 1] + sum[u << 1 | 1], al[u] = al[u << 1], ar[u] = ar[u << 1 | 1];
	if (ar[u << 1] == al[u << 1 | 1]) sum[u]--;
}
void build(int u, int L, int R)
{
	if (L == R)
	{
		sum[u] = 1, al[u] = ar[u] = a[rnk[L]];
		return;
	}
	int M = L + R >> 1;
	build(u << 1, L, M);
	build(u << 1 | 1, M + 1, R);
	pushup(u);
}
void update(int u, int L, int R, int l, int r, int x)
{
	if (l <= L && R <= r) maketag(u, x);
	else if (l <= R && L <= r)
	{
		int M = L + R >> 1;
		pushdown(u, L, R);
		update(u << 1, L, M, l, r, x);
		update(u << 1 | 1, M + 1, R, l, r, x);
		pushup(u);
	}
}
int query_l(int u, int L, int R, int l, int r)
{
	if (L == l && R == l) return al[u];
	else if (L <= l && l <= R)
	{
		int M = L + R >> 1;
		pushdown(u, L, R);
		return query_l(u << 1, L, M, l, r) + query_l(u << 1 | 1, M + 1, R, l, r);
	}
	else return 0;
}
int query_r(int u, int L, int R, int l, int r)
{
	if (L == r && R == r) return ar[u];
	else if (L <= r && r <= R)
	{
		int M = L + R >> 1;
		pushdown(u, L, R);
		return query_r(u << 1, L, M, l, r) + query_r(u << 1 | 1, M + 1, R, l, r);
	}
	else return 0;
}
int query(int u, int L, int R, int l, int r)
{
	if (l <= L && R <= r) return sum[u];
	else if (l <= R && L <= r)
	{
		int M = L + R >> 1;
		pushdown(u, L, R);
		int x = query(u << 1, L, M, l, r), y = query(u << 1 | 1, M + 1, R, l, r);
		if (x && y && query_r(u << 1, L, M, L, M) == query_l(u << 1 | 1, M + 1, R, M + 1, R)) return x + y - 1;
		else return x + y;
	}
	else return 0;
}
void update_sum(int x, int y, int z)
{
	int fx = top[x], fy = top[y];
	while (fx != fy)
	{
		if (dep[fx] >= dep[fy])
		{
			update(1, 1, n, dfn[fx], dfn[x], z);
			x = fa[fx];
		}
		else
		{
			update(1, 1, n, dfn[fy], dfn[y], z);
			y = fa[fy];
		}
		fx = top[x], fy = top[y];
	}
	if (dep[x] <= dep[y]) update(1, 1, n, dfn[x], dfn[y], z);
	else update(1, 1, n, dfn[y], dfn[x], z);
}
int query_sum(int x, int y)
{
	int fx = top[x], fy = top[y], ans = 0, lx = 0, ly = 0;
	while (fx != fy)
	{
		if (dep[fx] >= dep[fy])
		{
			ans += query(1, 1, n, dfn[fx], dfn[x]);
			if (query_r(1, 1, n, dfn[fx], dfn[x]) == lx) ans--;
			lx = query_l(1, 1, n, dfn[fx], dfn[x]), x = fa[fx];
		}
		else
		{
			ans += query(1, 1, n, dfn[fy], dfn[y]);
			if (query_r(1, 1, n, dfn[fy], dfn[y]) == ly) ans--;
			ly = query_l(1, 1, n, dfn[fy], dfn[y]), y = fa[fy];
		}
		fx = top[x], fy = top[y];
	}
	if (dfn[x] <= dfn[y])
	{
		ans += query(1, 1, n, dfn[x], dfn[y]);
		if (lx == query_l(1, 1, n, dfn[x], dfn[y])) ans--;
		if (ly == query_r(1, 1, n, dfn[x], dfn[y])) ans--;
	}
	else
	{
		ans += query(1, 1, n, dfn[y], dfn[x]);
		if (ly == query_l(1, 1, n, dfn[x], dfn[y])) ans--;
		if (lx == query_r(1, 1, n, dfn[x], dfn[y])) ans--;
	}
	return ans;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i];
	for (int i = 1; i < n; i++)
	{
		int x, y;
		cin >> x >> y;
		v[x].push_back(y), v[y].push_back(x);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	while (m--)
	{
		char op;
		int x, y, z;
		cin >> op >> x >> y;
		if (op == 'C')
		{
			cin >> z;
			update_sum(x, y, z);
		}
		else cout << query_sum(x, y) << '\n';
	}
	return 0;
}
2023/8/15 12:35
加载中...