题意:有一个数列,不知道数列里的数值,有多个询问,每个询问给出回答一段区间的和,但是有些是对的,有些是错的,保证如果无逻辑错误,则该回答认为是正确的,问哪些询问是错误的可以忽略。
对于询问区间和其实可以看做是前缀和,区间和也就是前缀和的差值,[a,b]的和就转换成 b 个元素的前缀和与 a-1 个元素的前缀和的差值,因此就转变为元素差值关系问题了,就可以用并查集与元素权值来判断,每个元素的权值代表其与根元素的值的差。注意读入 a、b 区间,需要对 a-1 和 b 进行合并。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5
6 int fa[200005],num[200005],n,m;
7
8 void init(){
9 for(int i=1;i<=n;i++){
10 fa[i]=i;
11 num[i]=0;
12 }
13 }
14
15 int find(int x){
16 int r=x,t1,t2,c=0;
17 while(r!=fa[r]){
18 c+=num[r];
19 r=fa[r];
20 }
21 while(x!=r){
22 t1=fa[x];
23 t2=c-num[x];
24 num[x]=c;
25 fa[x]=r;
26 c=t2;
27 x=t1;
28 }
29 return r;
30 }
31
32 int main(){
33 while(scanf("%d%d",&n,&m)!=EOF){
34 init();
35 int i,ans=0;
36 for(i=1;i<=m;i++){
37 int a,b,v;
38 cin>>a>>b>>v;
39 a--;
40 int x=find(a),y=find(b);
41 if(x==y){
42 if(num[b]-num[a]!=v)ans++;
43 }
44 else{
45 fa[y]=x;
46 num[y]=num[a]+v-num[b];
47 }
48 }
49 cout<<ans<<endl;
50 }
51 return 0;
52 }