55分求调
查看原帖
55分求调
526713
_111_楼主2023/5/29 17:49
#include <bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;
const int N = 1e5 + 10;
int n, m, cnt = 0, cntt = 0, LC, RC;
int head[N];
int fa[N], son[N], dep[N], sz[N], top[N], num[N];
ll a[N], w[N], lazy[4 * N], val[4 * N];
struct node {
	ll lx, rx;
	int l, r, ls, rs, val;
}t[4 * N];
struct Edge {
	int to, next;
}e[2 * N];
void add_edge(int u, int v) {
	e[++cnt].to = v;
	e[cnt].next = head[u];
	head[u] = cnt;
}
void dfs1(int x, int f) {
	fa[x] = f;
	dep[x] = dep[f] + 1;
	sz[x] = 1;
	for (int i = head[x]; i != -1; i = e[i].next) {
		if (e[i].to != f) {
			dfs1(e[i].to, x);
			sz[x] += sz[e[i].to];
			if (sz[son[x]] < sz[e[i].to]) son[x] = e[i].to;
		}
	}
}
void dfs2(int x, int t) {
	top[x] = t;
	num[x] = ++cntt;
	w[cntt] = a[x];
	if (!son[x]) return ;
	dfs2(son[x], t);
	for (int i = head[x]; i != -1; i = e[i].next) {
		if (e[i].to != fa[x] && e[i].to != son[x]) {
			dfs2(e[i].to, e[i].to);
		}
	}
}
void push_up(int pos) {
	//val[pos] = val[pos << 1] + val[pos << 1 | 1];
	t[pos].val = t[pos << 1].val + t[pos << 1 | 1].val;
	t[pos].ls = t[pos << 1].ls, t[pos].lx = t[pos << 1].lx;
	t[pos].rs = t[pos << 1 | 1].rs, t[pos].rx = t[pos << 1 | 1].rx;
	if (t[pos << 1].rx == t[pos << 1 | 1].lx) {
		t[pos].val--;
		if (t[pos << 1].ls == t[pos << 1].r - t[pos << 1].l + 1) {
			t[pos].ls += t[pos << 1 | 1].ls;
		}
		if (t[pos << 1 | 1].rs == t[pos << 1 | 1].r - t[pos << 1 | 1].l + 1) {
			t[pos].rs += t[pos << 1].rs;
		}
	}
}
node pushup(node x, node y) {
	node z;
	z.l = x.l, z.r = y.r;
	z.val = x.val + y.val;
	z.ls = x.ls, z.lx = x.lx;
	z.rs = y.rs, z.rx = y.rx;
	if (x.rx == y.lx) {
		z.val--;
		if (x.ls == x.r - x.l + 1) {
			z.ls += y.ls;
		}
		if (y.rs == y.r - y.l + 1) {
			z.rs += x.rs;
		}
	}
	return z;
}
void push_down(int pos, int l, int r) {
	if (lazy[pos]) {
		lazy[pos << 1] = lazy[pos];
		lazy[pos << 1 | 1] = lazy[pos];
		int mid = (l + r) >> 1;
		t[pos << 1].val = 1;
		t[pos << 1].lx = lazy[pos];
		t[pos << 1].rx = lazy[pos];
		t[pos << 1].ls = t[pos << 1].rs = t[pos << 1].r - t[pos << 1].l + 1;
		t[pos << 1 | 1].val = 1;
		t[pos << 1 | 1].lx = lazy[pos];
		t[pos << 1 | 1].rx = lazy[pos];
		t[pos << 1 | 1].ls = t[pos << 1 | 1].rs = t[pos << 1 | 1].r - t[pos << 1 | 1].l + 1;
		lazy[pos] = 0;
	}
}
void build(int pos, int l, int r) {
	t[pos].l = l, t[pos].r = r;
	lazy[pos] = 0;
	if (l == r) {
		t[pos].lx = t[pos].rx = w[l];
		t[pos].val = t[pos].ls = t[pos].rs = 1;
		return ;
	}
	int mid = (l + r) >> 1;
	build(pos << 1, l, mid);
	build(pos << 1 | 1, mid + 1, r);
	push_up(pos);
}
void update(int pos, int l, int r, int L, int R, ll k) {
	if (l > R || r < L) {
		return ;
	}
	if (L <= l && r <= R) {
		lazy[pos] = k;
		t[pos].val = 1;
		t[pos].lx = k, t[pos].rx = k;
		t[pos].ls = t[pos].rs = t[pos].r - t[pos].l + 1; 
		return ;
	}
	push_down(pos, l, r);
	int mid = (l + r) >> 1;
	update(pos << 1, l, mid, L, R, k);
	update(pos << 1 | 1, mid + 1, r, L, R, k);
	push_up(pos);
}
node query(int pos, int l, int r, int L, int R) {
	if (L <= l && r <= R) {
		if(l == L) LC = t[pos].lx;
    	if(r == R) RC = t[pos].rx;  
		return t[pos];
	}
	push_down(pos, l, r);
	int mid = (l + r) >> 1;
	int l1 = l, r1 = mid, l2 = mid + 1, r2 = r;
	if (l1 > R || r1 < L) {
		return query(pos << 1 | 1, mid + 1, r, L, R);
	} else if (l2 > R || r2 < L) {
		return query(pos << 1, l, mid, L, R);
	} else {
		return pushup(query(pos << 1, l, mid, L, R), query(pos << 1 | 1, mid + 1, r, L, R));
	}
}
void _update(int x, int y, int z) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		update(1, 1, n, num[top[x]], num[x], z);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	update(1, 1, n, num[x], num[y], z);
}
ll _query(int x, int y) {
	long long ans = 0;
	int p = 0, q = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) swap(x, y), swap(p, q);
		ans += query(1, 1, n, num[top[x]], num[x]).val;
		if (RC == p) ans--;
		p = LC;
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
	ans += query(1, 1, n, num[x], num[y]).val;
	if (LC == p) ans--;
	if (RC == q) ans--;
	return ans;
}
signed main() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; i++) {
		head[i] = -1;
	}
	for (int i = 1; i <= n; i++) {
		scanf("%lld", &a[i]);
	}
	for (int i = 1; i <= n - 1; i++) {
		int u, v;
		scanf("%lld%lld", &u, &v);
		add_edge(u, v);
		add_edge(v, u);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	for (int i = 1; i <= m; i++) {
		char op;
		cin >> op;
		if (op == 'C') {
			int x, y, z;
			scanf("%lld%lld%lld", &x, &y, &z);
			_update(x, y, z);
		} else {
			int x, y;
			scanf("%lld%lld", &x, &y);
			printf("%lld\n", _query(x, y));
		}
	}
	return 0;
}
2023/5/29 17:49
加载中...