TLE70 求条
查看原帖
TLE70 求条
649315
心灵震荡楼主2025/1/12 22:13

rt,码风相当清晰/kel

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, m, dfn[N], rk[N], w[N], a, b, c, idx, u, v, k;
int top[N], dep[N], f[N], heavy[N], siz[N];
char opt;
vector<int> g[N];

void dfs1(int u, int fa)
{
	f[u] = fa, siz[u] = 1;
	dep[u] = dep[fa] + 1;
	for(auto v : g[u])
	{
		if(v == fa) continue;
		dfs1(v, u), siz[v] += siz[u];
		if(siz[v] > siz[heavy[u]]) heavy[u] = v;
	}
	return;
}

void dfs2(int u, int tp)
{
	top[u] = tp, dfn[u] = ++idx;
	rk[dfn[u]] = u;
	if(!heavy[u]) return;
	dfs2(heavy[u], tp);
	for(auto v : g[u])
		if(v != f[u] && v != heavy[u]) dfs2(v, v);
	return;
}

struct node
{
	int l, r, cl, cr, val, tag;
} tree[N << 2];

void pushup(int x)
{
	if(tree[x].l == tree[x].r) return;
	tree[x].val = tree[x << 1].val + tree[x << 1 | 1].val;
	tree[x].val -= (tree[x << 1].cr == tree[x << 1 | 1].cl);
	tree[x].cl = tree[x << 1].cl;
	tree[x].cr = tree[x << 1 | 1].cr;
	return;
}

void pushdown(int x)
{
	if(!tree[x].tag) return;
	tree[x << 1].tag = tree[x << 1 | 1].tag = tree[x].tag;
	tree[x << 1].cl = tree[x << 1 | 1].cl = tree[x].tag;
	tree[x << 1].cr = tree[x << 1 | 1].cr = tree[x].tag;
	tree[x << 1].val = tree[x << 1 | 1].val = 1;
	tree[x].tag = 0;
	return;
}

void build(int l, int r, int x)
{
	tree[x] = {l, r, 0, 0, 0, 0};
	if(l == r)
	{
		tree[x].cl = tree[x].cr = w[rk[l]];
		tree[x].val = 1;
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, x << 1);
	build(mid + 1, r, x << 1 | 1);
	pushup(x);
	return;
}

void update(int l, int r, int k, int x)
{
	if(l <= tree[x].l && tree[x].r <= r)
	{
		tree[x].cl = tree[x].cr = tree[x].tag = k;
		tree[x].val = 1;
		return;
	}
	int mid = (tree[x].l + tree[x].r) >> 1;
	pushdown(x);
	if(l <= mid) update(l, r, k, x << 1);
	if(mid < r) update(l, r, k, x << 1 | 1);
	pushup(x);
	return;
}

struct noti
{
	int cl, cr, val;
};

noti merge(noti x, noti y)
{
	return (noti) {x.cl, y.cr, x.val + y.val - (x.cr == y.cl)};
}

int query_col(int p, int x)
{
	if(p <= tree[x].l && tree[x].r <= p) return tree[x].cl;
	int mid = (tree[x].l + tree[x].r) >> 1;
	pushdown(x);
	if(p <= mid) return query_col(p, x << 1);
	else return query_col(p, x << 1 | 1);
}

noti query(int l, int r, int x)
{
	if(l <= tree[x].l && tree[x].r <= r)
		return {tree[x].cl, tree[x].cr, tree[x].val};
	int mid = (tree[x].l + tree[x].r) >> 1;
	pushdown(x);
	if(l <= mid && mid < r) return merge(query(l, r, x << 1), query(l, r, x << 1 | 1));
	else if(l <= mid) return query(l, r, x << 1);
	else return query(l, r, x << 1 | 1);
}

void modify(int x, int y, int k)
{
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x, y);
		update(dfn[top[x]], dfn[x], k, 1);
		x = f[top[x]];
	}
	if(dep[x] < dep[y]) swap(x, y);
	update(dfn[y], dfn[x], k, 1);
	return;
}

int ask(int x, int y)
{
	int res = 0;
	while(top[x] != top[y])
	{
		if(dep[top[x]] < dep[top[y]]) swap(x, y);
		res += query(dfn[top[x]], dfn[x], 1).val;
		res -= (query_col(dfn[top[x]], 1) == query_col(dfn[f[top[x]]], 1));
		x = f[top[x]];
	}
	if(dep[x] < dep[y]) swap(x, y);
	res += query(dfn[y], dfn[x], 1).val;
	return res;
}

int main()
{
	ios :: sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; i++) cin >> w[i];
	for(int i = 1; i < n; i++)
	{
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, n, 1);
	for(int i = 1; i <= m; i++)
	{
		cin >> opt;
		if(opt == 'C')
		{
			cin >> a >> b >> c;
			modify(a, b, c);
		}
		else
		{
			cin >> a >> b;
			cout << ask(a, b) << '\n';
		}
	}
	return 0;
}
2025/1/12 22:13
加载中...