How Many Answers Are Wrong——带权并查集
题意:
有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已经给出的是矛盾的。
例:
【1,5】 = 10 ,【6.10】 = 10, 【1, 10】 = 30,这明显第三个与前面两个矛盾。
题解:
sum【i】 表示 1到i的和 如果存在 【i,a】与【i,b】 则只要判断 【b,i】- 【a-1,i】是否等于 c 即可
所以用并查集维护公共点 即根节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<stdio.h> #include<math.h> using namespace std; typedef long long ll; const int maxn=2e5+5; int f[maxn]; int n,m; int sum[maxn];///根节点到 i 的距离 int Find(int x) { if(x==f[x])return x; int root=Find(f[x]); sum[x]+=sum[f[x]]; return f[x]=root; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=0;i<=n;i++)f[i]=i,sum[i]=0; int ans=0; while(m--) { int a,b,s; scanf("%d%d%d",&a,&b,&s); a--; int fx=Find(a); int fy=Find(b); if(fx!=fy) { f[fy]=fx; sum[fy]=sum[a]+s-sum[b];/// sum[b]+sum[fy]-sum[a]=s } else { if(sum[b]-sum[a]!=s)ans++; } } printf("%d\n",ans); } return 0; }