题意 : 给你m个区间的区间和,让你判断有多少个答案是错误的。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 2e5 + 10;
int sum[maxn] = {0};
int p[maxn] = {0};
int find (int x) {
if (x == p[x]) return x;
int root = find (p[x]);
sum[x] += sum[p[x]];
p[x] = root;
return root;
}
int ans = 0;
int main () {
ios_base :: sync_with_stdio(false);
int n,m;
while (cin >> n >> m){
for (int i = 0;i <= n; ++ i) p[i] = i,sum[i] = 0;
ans = 0;
for (int i = 0;i < m; ++ i) {
int l,r,val;
cin >> l >> r >> val;
--l;
int pl = find (l);
int pr = find (r);
if (pl != pr) {
p[pr] = pl;
sum[pr] = sum[l] - sum[r] + val;
}
else if (sum[r] - sum[l] != val) ans ++;
}
cout << ans << endl;
}
return 0;
}
。每一个集合中每个数的权值是这个点的前缀和减去根结点的前缀和。每次合并集合的时候只需要把一个集合的根节点的值设置为这个根节点的值减去要合并到根节点的值,然后将两个集合合并即可。