简单题 40 pts 求调
查看原帖
简单题 40 pts 求调
864150
Bpds1110楼主2024/8/28 18:50

rt。用带权并查集维护。

#include <bits/stdc++.h>
typedef long long ll;
#define int long long

const int N = 2e5 + 10; 

// lst[i] 表示 i 元素的最终状态的节点
// 每个元素 i 的初始状态节点为 i
// T = n + m + 1
// U = n + m + 2
// 权值为 1 时表相同,0 时表相反

int n, m, lst[N], anc[N];

int val[N]; // val[i] 表示节点 i 到其父亲节点的边权,路径压缩后表示到根节点的边权

int find(int x) {
	if (x != anc[x]) {
		int fa = anc[x];
		anc[x] = find(fa);
		(val[x] += val[fa]) &= 1; 	
	}
	return anc[x]; 
}

int path_len(int u, int v) {
	int ancu = find(u), ancv = find(v);
	if (ancu != ancv) return -1;
	return val[u] + val[v] & 1;
}

void merge(int u, int v, int d) {
	int ancu = find(u), ancv = find(v);
	if (ancu != ancv) { // ancu --> ancv
		val[ancv] = d + 2 - (val[u] + val[v] & 1) & 1;
		anc[ancv] = ancu;
	}
	return void();
}

std::vector <int> vec; 

void solve() {
	std::cin >> n >> m;
	for (int i = 1; i <= n; ++ i) lst[i] = i;
	int _idx = n + m + 2;
	for (int i = 1; i <= _idx; ++ i) anc[i] = i, val[i] = 0; 
	int idx = n; 
	while (m --> 0) {
		char op; std::cin >> op;
		if (op == 'T' || op == 'F' || op == 'U') {
			int id; std::cin >> id;
			lst[id] = ++ idx;
			if (op == 'T') merge(idx, _idx - 1, 0);
			if (op == 'F') merge(idx, _idx - 1, 1);
			if (op == 'U') merge(idx, _idx, 0);
		}  
		else {
			int i, j; std::cin >> i >> j;
			if (op == '+') merge(idx + 1, lst[j], 0);
			if (op == '-') merge(idx + 1, lst[j], 1); 
			lst[i] = ++ idx;
		}
	}
	int cnt = 0; 
	vec.clear(); 
	for (int i = 1; i <= n; ++ i) if (path_len(lst[i], i) == 1) vec.push_back(i);
	for (auto i : vec) merge(i, _idx, 0);  
//	for (int i = 1; i <= n; ++ i) std::cout << anc[i] << " "; std::cout << "\n"; 
	for (int i = 1; i <= n; ++ i) merge(i, lst[i], 0);
//	std::cout << fU << "\n"; 
	for (int i = 1; i <= n; ++ i)
		if (find(i) == find(_idx)) ++ cnt;
	
//	for (int i = 1; i <= n; ++ i) std::cout << anc[i] << " "; std::cout << "\n"; 
	
	std::cout << cnt << "\n";
	return void(); 
}

signed main() {

//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);

	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);

	int type, _; std::cin >> type >> _;
	while (_ --> 0) {
		solve(); 
	}

	return 0;
}

2024/8/28 18:50
加载中...