只过了Hack求调
查看原帖
只过了Hack求调
573963
wbh20090611楼主2024/7/12 10:36
#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
using namespace std;
const int N = 200005;
vector <int> e[N];
int a[N], n, lll;
int top[N], dep[N], son[N], size[N], f[N];
int dfn[N], wz[N];
char c;
void dfs1(int x, int fa)
{
	f[x] = fa;
	dep[x] = dep[fa] + 1;
	size[x] = 1;
	for (auto i : e[x])
	{
		if (i == fa)
			continue;
		dfs1(i, x);
		size[x] += size[i];
		if(size[son[x]] < size[i])
			son[x] = i;
	}
	return;
}
void dfs2(int x, int t)
{
	dfn[x] = ++lll;
	wz[lll] = x;
	top[x] = t;
	if (!son[x])
		return;
	dfs2(son[x], t);
	for(auto i : e[x])
	{
		if (i == f[x] || i == son[x])
			continue;
		dfs2(i, i);
	}
}
struct p
{
	int a, b, c;
};
class Tree
{
	private:
		int sum[N << 2], lef[N << 2], rig[N << 2];
	public:
		void build(int root, int l, int r)
		{
			if (l == r)
			{
				lef[root] = rig[root] = a[wz[l]];
				sum[root] = 1;
				return;
			}
			build(root << 1, l, mid);
			build(root << 1 | 1, mid + 1, r);
			if (rig[root << 1] == lef[root << 1 | 1])
				sum[root] = sum[root << 1] + sum[root << 1 | 1] - 1;
			else
				sum[root] = sum[root << 1] + sum[root << 1 | 1];
			lef[root] = lef[root << 1];
			rig[root] = rig[root << 1 | 1];
		}
		void push_down(int root)
		{
			if(sum[root] == 1)
			{
				sum[root << 1] = sum[root << 1 | 1] = 1;
				lef[root << 1] = lef[root << 1 | 1] = rig[root << 1] = rig[root << 1 | 1] = lef[root];
			}
			return;
		}
		void change(int root, int l, int r, int c)
		{
			sum[root] = 1;
			lef[root] = rig[root] = c;
			push_down(root);
			return;
		}
		void update(int root, int l, int r, int x, int y, int c)
		{
			if (l >= x && r <= y)
			{
				change(root, l, r, c);
				return;
			}
			push_down(root);
			if (y > mid)
				update(root << 1 | 1, mid + 1, r, x, y, c);
			if (x <= mid)
				update(root << 1, l, mid, x, y, c);
			if (rig[root << 1] == lef[root << 1 | 1])
				sum[root] = sum[root << 1] + sum[root << 1 | 1] - 1;
			else
				sum[root] = sum[root << 1] + sum[root << 1 | 1];
			lef[root] = lef[root << 1];
			rig[root] = rig[root << 1 | 1];
			return;
		}
		p query(int root, int l, int r, int x, int y)
		{
			if (l >= x && r <= y)
			{
				return {sum[root], lef[root], rig[root]};
			}
			this->push_down(root);
			p a = {0, 0, 0}, b = {0, 0, 0};
			if (y > mid)
				b = query(root << 1 | 1, mid + 1, r, x, y);
			if (x <= mid)
				a = query(root << 1, l, mid, x, y);
			if (rig[root << 1] == lef[root << 1 | 1])
				sum[root] = sum[root << 1] + sum[root << 1 | 1] - 1;
			else
				sum[root] = sum[root << 1] + sum[root << 1 | 1];
			lef[root] = lef[root << 1];
			rig[root] = rig[root << 1 | 1];
			if (a.a && b.a)
			{
				if (rig[root << 1] == lef[root << 1 | 1])
					return {a.a + b.a - 1, a.b, b.c};
				return {a.a + b.a, a.b, b.c};
			}
			else if (a.a)
				return a;
			else
				return b;
		}
}tree;
void update_lca(int x, int y, int z)
{
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		tree.update(1, 1, n, dfn[top[x]], dfn[x], z);
		x = f[top[x]];
	}
	if (dfn[x] > dfn[y])
		swap(x, y);
	tree.update(1, 1, n, dfn[x], dfn[y], z);
}
int lca(int x, int y)
{
	while (top[x] != top[y])
	{
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		x = f[top[x]];
	}
	if (dep[x] < dep[y])
		return x;
	else
		return y;
}
int query_lca(int x, int y)
{
	int ans = 0, fa = lca(x, y), ff;
	ff = fa;
	p u = {-1, -1, -1}, v;
	while (top[x] != top[fa])
	{
		if (dep[top[x]] < dep[top[fa]])
			swap(x, fa);
		v = u;
		u = tree.query(1, 1, n, dfn[top[x]], dfn[x]);
		if (v.c == u.b)
			ans--;
		ans += u.a;
		x = f[top[x]];
	}
	v = u;
	u = tree.query(1, 1, n, dfn[fa], dfn[x]);
	if (v.c == u.b)
		ans--;
	ans += u.a;
	fa = ff;
	u = {-1, -1, -1};
	while (top[y] != top[fa])
	{
		if (dep[top[y]] < dep[top[fa]])
			swap(y, fa);
		v = u;
		u = tree.query(1, 1, n, dfn[top[y]], dfn[y]);
		if (v.c == u.b)
			ans--;
		ans += u.a;
		y = f[top[y]];
	}
	v = u;
	u = tree.query(1, 1, n, dfn[fa], dfn[y]);
	if (v.c == u.b)
		ans--;
	ans += u.a;
	return ans - 1;
}
int q, x, y, z;
int main()
{
	cin >> n >> q;
	for(int i = 1; i <= n; i++)
		scanf("%d", a + i);
	for (int i = 1, u, v; i < n; i++)
	{
		scanf("%d%d", &u, &v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	tree.build(1, 1, n);
	while(q--)
	{
		cin >> c;
		if (c == 'Q')
		{
			scanf("%d%d",&x, &y);
			printf("%d\n", query_lca(x, y));
		}
		else
		{
			scanf("%d%d%d", &x, &y, &z);
			update_lca(x, y, z);
		}
	}
}
2024/7/12 10:36
加载中...