调的吐血了
查看原帖
调的吐血了
675527
Play_CP_4fun楼主2022/12/2 09:16
/*
Author: SJ

general 
1.shuzu buyao kai xiaole
2.0 1 zhe liangge tepan
3.dfs jide biaoji qidian
4.changdaima jide fenbu tiaoshi
5.yao xihuanshang heihezi

str
1.yongle s.substr(), jide kanyixiashibushikeyi yigeyige shuchu

THINK TWICE, CODE ONCE.
Duo xiang ti, Shao jiao lv.
*/
#include<bits/stdc++.h>
const int N = 5e4 + 10;
using ll = long long;
using ull = unsigned long long;
/* 
这道题中, val[x]的含义即x与根节点的距离, 
它模三即他与根节点种类的关系
余1剩余类即被根节点吃
余2剩余类即吃根节点
余0剩余类即和根节点同类

只有x, y同一个集合, 才能判断此语句真假
*/
int n, k, fa[N], val[N], ans;
void init() {
	for (int i = 1; i <= n; i++) fa[i] = i;
}
int find(int x) {
	if (x != fa[x]) {
		int t = fa[x];
		fa[x] = find(fa[x]);
		val[x] += val[fa[x]];
	}
	return fa[x];
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	std::cin >> n >> k;
	init();

	while (k--) {
		int d, x, y;
		std::cin >> d >> x >> y;

		if (x > n || y > n || (x == y && d == 2)) {
			ans++;
			continue;
		}

		int xx = find(x);
		int yy = find(y);

		if (xx == yy) {
			if (d == 1) {
				if ((val[x] - val[y]) % 3) ans++;
			} else if (d == 2) {
				if ((val[x] + 1 - val[y]) % 3) ans++;
			} 
		} else {
			if (d == 1) {
				fa[yy] = xx;
				val[yy] = val[x] - val[y];
				while (val[yy] < 0) val[yy] += 3;
			} else if (d == 2) {
				fa[yy] = xx;
				val[yy] = val[x] - val[y] + 1;
				while (val[yy] < 0) val[yy] += 3;
			}
		}
	}
	// for (int i = 1; i <= 3; i++) {
	// 	std::cout << fa[i] << ' ' << val[i] << "\n";
	// }
	std::cout << ans;
	return 0;
}
2022/12/2 09:16
加载中...