题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038
题意:对于给定的a1..an,通过询问下标x..y,给出a[x]+...+a[y],但给出的值可能是错的,需要判断,因为题目说的是整数,也可能是负整数,所以逻辑错误只有一种情况:给了a..c的值x,a..b的值y,之后又给了b..c的值z,若x!=y+z,则是错误答案,否则是正确答案。
思路:
参考巨巨的博客:https://www.cnblogs.com/liyinggang/p/5327055.html。
用root数组表示祖先,dis数组表示到祖先的距离(如对于数据1 2 3,3的祖先为1,则dis[3]=1+2=3),都需要初始化。
每次询问输入a,b,s,同时--b,ra=getr(a),rb=getr(b)。
1.ra!=rb:则合并
令root[rb]=ra,dis[rb]=dis[a]+s-dis[b](画图模拟一下,记住此处的b加一了)
2.ra==rb:则查询
若dis[b]-dis[a]!=s,则为错误答案。
最后注意这道题是多组数据输入,详见代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=200005; 5 int n,m,a,b,s,res; 6 int root[maxn],dis[maxn]; 7 8 int getr(int k){ 9 if(root[k]==k) return k; 10 else{ 11 int tmp=root[k]; 12 root[k]=getr(root[k]); 13 dis[k]+=dis[tmp]; 14 return root[k]; 15 } 16 } 17 18 int main(){ 19 while(~scanf("%d%d",&n,&m)){ 20 res=0; 21 for(int i=1;i<=n+1;++i) 22 root[i]=i,dis[i]=0; 23 while(m--){ 24 scanf("%d%d%d",&a,&b,&s); 25 ++b; 26 int ra=getr(a),rb=getr(b); 27 if(ra==rb){ 28 if(dis[b]-dis[a]!=s) 29 ++res; 30 } 31 else{ 32 root[rb]=ra; 33 dis[rb]=dis[a]+s-dis[b]; 34 } 35 } 36 printf("%d ",res); 37 } 38 return 0; 39 }