样例 + Hack 可过, 但是其他全Wa 求调 >w<
查看原帖
样例 + Hack 可过, 但是其他全Wa 求调 >w<
670455
ska_0x08楼主2022/11/22 12:52
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 1145;
struct T {
	int front, back, num, flag;
}tr[N << 2];
int n, m;
int top[N], dep[N], dfn[N], idx = 0, fa[N], h_son[N], id[N], siz[N], a[N]; 
vector <int> e[N];

void push_down (int rt){
	if (tr[rt].flag) {
		int col = tr[rt].flag;  
		tr[rt << 1] = {col, col, 1, col};
		tr[rt << 1 | 1] = {col, col, 1, col};
		tr[rt].flag = 0;
	}
}

void push_up (int rt) {
	if (tr[rt << 1].num == 0 && tr[rt << 1 | 1].num == 0) return ;
	if (tr[rt << 1].num == 0) {
		tr[rt] = tr[rt << 1 | 1];
		return ;
	}
	if (tr[rt << 1 | 1].num == 0) {
		tr[rt] = tr[rt << 1];
		return ;
	}
	
	tr[rt].front = tr[rt << 1].front;
	tr[rt].back = tr[rt << 1 | 1].back;
	tr[rt].num = tr[rt << 1].num + tr[rt << 1 | 1].num - (tr[rt << 1].back == tr[rt << 1 | 1].front);
}

void update (int rt, int l, int r, int L, int R, int col){
	if (L <= l && r <= R) {
		tr[rt] = {col, col, 1, col};
		return;
	}	
	push_down (rt);
	int mid = (l + r) >> 1;
	if (L <= mid) update (rt << 1, l, mid, L, R, col);
	if (mid < R) update (rt << 1 | 1, mid + 1, r, L, R, col);
	push_up (rt);
}

void Color (int u, int v, int col) {
	while (top[u] != top[v]) {
		if (dep[top[u]] > dep[top[v]]) {
			update (1, 1, n, dfn[top[u]], dfn[u], col);
			u = fa[top[u]];
		} else {
			update (1, 1, n, dfn[top[v]], dfn[v], col);
			v = fa[top[v]];
		}
	}
	if (dep[u] < dep[v])
		update (1, 1, n, dfn[u], dfn[v], col);
	else update (1, 1, n, dfn[v], dfn[u], col);
}

void build (int rt, int l, int r) {
	tr[rt] = {0, 0, 0, 0};
	if (l == r) {
		tr[rt] = {a[dfn[l]], a[dfn[l]], 1, 0};
		return ;
	}
	
	int mid = (l + r) >> 1;
	build (rt << 1, l, mid);
	build (rt << 1 | 1, mid + 1, r);
	push_up(rt);
}

void merg (T &a, T b) {
//	a.back = b.back;
	if (a.num == 0) {a = b; return;}
	a.num = a.num + b.num - (a.back == b.front);
	a.back = b.back;
}

T query (int rt, int l, int r, int L, int R) {
	if (L <= l && r <= R) 
		return tr[rt];
	int mid = (l + r) >> 1;
	push_down (rt);
	T tmp;
	tmp = {0, 0, 0, 0};
	if (L <= mid) merg (tmp, query (rt << 1, l, mid, L, R));
	if (mid < R) merg (tmp, query (rt << 1 | 1, mid + 1, r, L, R));
	push_up (rt);
	return tmp;
}

void dfs1 (int u, int f){
	fa[u] = f;
	siz[u] = 1;
	dep[u] = dep[f] + 1;
	h_son[u] = -1;
	for(int i = 0; i < e[u].size(); i ++){
		int v = e[u][i];
		if (v == f) continue;
		dfs1(v, u);
		siz[u] += siz[v];
		if ( (h_son[u] == -1) || siz[v] > siz[h_son[u]])
			h_son[u] = v;
	}
}

void dfs2 (int u, int tp){
	dfn[u] = ++ idx;
	top[u] = tp;
	id[idx] = u;
	if (h_son[u] != -1)
		dfs2 (h_son[u], tp);
	for (int i = 0; i < e[u].size(); i ++) {
		int v = e[u][i];
		if(v == fa[u] || v == h_son[u]) continue;
		dfs2 (v, v);
	}
}

int Query (int u, int v) {
	T tmp;
//	cout << tmp_u.num << endl;
	int frou = -1, frov = -1;  
	int ans = 0;
	while (top[u] != top[v]) {
		if (dep[top[u]] > dep[top[v]]) {
			tmp = query (1, 1, n, dfn[top[u]], dfn[u]);
			ans += tmp.num;
			if (frou == tmp.back)
				ans --;
			frou = tmp.front;
			u = fa[top[u]];
		} else {
			tmp = query (1, 1, n, dfn[top[v]], dfn[v]);
			ans += tmp.num;
			if (frov == tmp.back)
				ans --;
			frov = tmp.front;
			v = fa[top[v]];
		}
	}
	
	if (dep[u] < dep[v]) {
		tmp = query (1, 1, n, dfn[u], dfn[v]);
		ans += tmp.num;
		if (tmp.back == frov)
			ans --;
		if (tmp.front == frou)
			ans --;
//		ans = tmp_v.num + tmp_u.num - (tmp_v.front == tmp_u.front);
		return ans;
	}
	
	tmp = query (1, 1, n, dfn[v], dfn[u]);
	ans += tmp.num;
	if (tmp.back == frou)
		ans --;
	if (tmp.front == frov)
		ans --;
//	tmp_u = tmp;
//	ans = tmp_v.num + tmp_u.num - (tmp_v.front == tmp_u.front);
	return ans;
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++)
		scanf ("%d", &a[i]);
		
	for (int i = 1; i < n; i ++) {
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	
	dfs1(1, 0);
	dfs2(1, 1);
	build (1, 1, n);
	while (m --) {
		char op;
		cin >> op;
		int u, v, c;
		scanf ("%d%d", &u, &v);
		if (op == 'C') {
			scanf ("%d", &c);
			Color (u, v, c);//路径上染色
		} else {
			printf ("%d\n", Query (u, v));//查询
		}
	}
	return 0;
}
2022/11/22 12:52
加载中...