0pts求条宣1管
查看原帖
0pts求条宣1管
1198462
dvsfanjo楼主2025/1/7 19:53
#include <bits/stdc++.h>
#define pb push_back
#define ls (i<<1)
#define rs (i<<1|1)
#define mid ((l+r)>>1)
using namespace std;
using ll = long long;
const int maxn = 1e5 + 5;
ll n, q, u, v, k; char opt;
ll val[maxn], dep[maxn], fat[maxn], top[maxn], son[maxn], siz[maxn], ide[maxn];
vector <ll> G[maxn];
ll tot, a[maxn], tag[maxn << 2];
struct node {
	ll le, ri, cnt;
	inline void init() {
		le = ri = cnt = -1;
		return;
	}
	inline node sawp() {
		return node{ri, le, cnt};
	}
	friend bool operator == (node a, node b) {
		return a.le == b.le && a.ri == b.ri && a.cnt == b.cnt;
	}
	friend node operator + (node a, node b) {
		if (a == node{-1, -1, -1}) return b;
		if (b == node{-1, -1, -1}) return a;
		return node{a.le, b.ri, a.cnt + b.cnt - (a.ri == b.le ? 1 : 0)};
	}
} t[maxn << 2];
void dfs1(ll u, ll fa) {
	dep[u] = dep[fa] + 1;
	fat[u] = fa;
	siz[u] = 1;
	for (auto g : G[u]) {
		if (g == fa) continue;
		dfs1(g, u);
		if (siz[son[u]] < siz[g]) {
			son[u] = g;
		}
		siz[u] += siz[g];
	}
	return;
}
void dfs2(ll u, ll T) {
	top[u] = T;
	ide[u] = ++tot;
	a[tot] = val[u];
	if (son[u]) dfs2(son[u], T);
	for (auto g : G[u]) {
		if (g == fat[u] || g == son[u]) continue;
		dfs2(g, g);
	}
	return;
}
void build(ll l, ll r, ll i) {
	tag[i] = -1;
	if (l == r) {
		t[i] = {a[l], a[r], 1};
		return;
	}
	build(l, mid, ls);
	build(mid + 1, r, rs);
	t[i] = t[ls] + t[rs];
//	cout << l << ' ' << r << ' ' << t[i].le << ' ' << t[i].ri << ' ' << t[i].cnt << '\n';
	return; 
}
inline void apply(ll i, ll v) {
	if (v == -1) return;
	tag[i] = v;
	t[i].le = t[i].ri = v;
	t[i].cnt = 1;
	return;
}
inline void pushdown(ll i) {
	apply(ls, tag[i]);
	apply(rs, tag[i]);
	return;
}
void update(ll l, ll r, ll i, ll a, ll b, ll k) {
	if (a <= l && r <= b) {
		apply(i, k);
		return;
	}
	pushdown(i);
	if (a <= mid) update(l, mid, ls, a, b, k);
	if (mid < b) update(mid + 1, r, rs, a, b, k);
	t[i] = t[ls] + t[rs];
	return;
}
node query(ll l, ll r, ll i, ll a, ll b) {
	if (a <= l && r <= b) return t[i];
	node ans; ans.init();
	if (a <= mid) ans = ans + query(l, mid, ls, a, b);
	if (mid < b) ans = ans + query(mid + 1, r, rs, a, b);
	return ans;
}
ll lca(ll u, ll v) {
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		u = fat[top[u]];
	}
	return dep[u] > dep[v] ? v : u;
}
void lca_update(ll u, ll v, ll k) {
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		update(1, n, 1, ide[top[u]], ide[u], k);
		u = fat[top[u]];
	}
	if (dep[u] < dep[v]) swap(u, v);
	update(1, n, 1, ide[v], ide[u], k); 
	return;
}
ll lca_query(ll u, ll v) {
	node a1, a2, b, ans; a1.init(); a2.init();
	ll Lca = lca(u, v);
	while (top[u] != top[Lca]) {
		b = query(1, n, 1, ide[top[u]], ide[u]);
		a1 = b + a1;
//		cout << "a1:" << ide[top[u]] << ' ' << ide[u] << '\n';
//		cout << b.le << ' ' << b.ri << ' ' << b.cnt << "\n\n";
		u = fat[top[u]];
	}
	while (top[v] != top[Lca]) {
		b = query(1, n, 1, ide[top[v]], ide[v]).sawp();
		a2 = b + a2;
//		cout << "a2:" << ide[top[v]] << ' ' << ide[v] << '\n';
//		cout << b.le << ' ' << b.ri << ' ' << b.cnt << "\n\n";
		v = fat[top[v]];
	}
	if (u == Lca) {
		b = query(1, n, 1, ide[u], ide[v]).sawp();
		a2 = b + a2;
//		cout << "a2:" << ide[u] << ' ' << ide[v] << '\n';
//		cout << b.le << ' ' << b.ri << ' ' << b.cnt << "\n\n";
	} else {
		b = query(1, n, 1, ide[v], ide[u]);
		a1 = b + a1;
//		cout << "a1:" << ide[v] << ' ' << ide[u] << '\n';
//		cout << b.le << ' ' << b.ri << ' ' << b.cnt << "\n\n";
	}
	ans = a1 + a2;
	return ans.cnt;
}
void ch(ll l, ll r, ll i) {
	cout << l << ' ' << r << ' ' << t[i].le << ' ' << t[i].ri << ' ' << t[i].cnt << '\n';
	if (l == r) return;
	ch(l, mid, ls);
	ch(mid + 1, r, rs);
	return;
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	cin >> n >> q;
	for (int i = 1; i <= n; i++) {
		cin >> val[i];
	} 
	for (int i = 1; i < n; i++) {
		cin >> u >> v;
		G[u].pb(v); G[v].pb(u);
	}
	dfs1(1, 0);
	
	dfs2(1, 1);

	build(1, n, 1);
	
	
	
//	for (int i = 1; i <= n; i++) {
//		cout << "Id " << i << " ide " << ide[i] << " a " << a[ide[i]] << '\n'; 
//	}
	
	for (int i = 1; i <= q; i++) {
		cin >> opt >> u >> v;
		if (opt == 'Q') {
			cout << lca_query(u, v) << '\n';
		} else {
			cin >> k;
			lca_update(u, v, k);
		}
	}
	return 0;
}
/*
2 1 1 1 1 1

1 2 4 6 5 3
*/

真是有点母亲!

2025/1/7 19:53
加载中...