WIKI
带权并查集
FF 可以从中选择一个连续的子序列
问 TT 他选择的子序列的和是多少
接下来,TT 会回答 FF 的问题
然后,FF 可以重做这个过程
TT 根本不想和 FF 玩。为了惩罚 FF,她经常故意告诉 FF 错误的答案。
FF 发现有些答案是矛盾的
保证只要没有逻辑错误,答案都是正确的。
如果 FF 发现某个答案是错的,他在判断下一个答案时就会忽略它。
输出单行整数表示有多少个答案是错误的。
code
#include <iostream>
using namespace std;
int n, m;
const int N = 2E5 + 10;
int p[N], val[N], ans;
int find(int u) {
if (p[u] == u)
return u;
else {
int tmp = p[u];
p[u] = find(p[u]);
val[u] += val[tmp];
return p[u];
}
}
void merge(int a, int b, int v) {
int fa = find(a), fb = find(b);
if (fa != fb) {
p[fa] = fb;
val[fa] = val[b] - val[a] - v;
} else {
if (val[a] + v != val[b]) ans++;
}
}
void solve() {
while (cin >> n >> m) {
for (int i = 0; i <= n; i++) {
p[i] = i;
val[i] = 0;
}
ans = 0;
while (m--) {
int a, b, c;
cin >> a >> b >> c;
a--;
merge(a, b, c);
}
cout << ans << "\n";
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
solve();
return 0;
}
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是”1 X Y”,表示X和Y是同类。
第二种说法是”2 X Y”,表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。
Input
第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。
Output
只有一个整数,表示假话的数目。
code
#include <iostream>
using namespace std;
int n, m;
const int N = 50005;
int p[N], val[N], ans;
int find(int u) {
if (p[u] == u)
return u;
else {
int tmp = p[u];
p[u] = find(p[u]);
(val[u] += val[tmp]) %= 3;
return p[u];
}
}
void merge(int a, int b, int c) {
int fa = find(a), fb = find(b);
if (fa != fb) {
p[fa] = fb;
val[fa] = (val[b] - val[a] + c) % 3;
} else if (c != (val[a] - val[b] + 3) % 3)
ans++;
}
void solve() {
cin >> n >> m;
for (int i = 0; i < N; i++) p[i] = i, val[i] = 0;
while (m--) {
int a, b, c;
cin >> a >> b >> c;
a--;
if (b > n or c > n or (a == 1 and b == c))
ans++;
else
merge(b, c, a);
}
cout << ans << "\n";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
solve();
return 0;
}