Description
A有一个由n个数组成的序列,B问A一系列问题A回答,每次B询问区间[a,b]中所有数之和,A的可能说真话也可能说假话,此处认为如果未出现冲突则A说的是真话,共m次询问,问A说假话的次数
Input
第一行为两个整数n和m分别表示序列长度和询问次数,之后m行每行三个整数a,b,s表示[a,b]中所有数之和为s(1<=n<=200000,1<=m<=40000,1<=a<=b<=n,所有数据在int范围内)
Output
输出假话数量
Sample Input
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
Sample Output
1
Solution
将[a,b]中所有数之和为s看作是b比a-1大s,问题转化为简单并查集
Code
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 222222
int n,m,a,b,s,fa[maxn],sum[maxn];
void init(int n)
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
sum[i]=0;
}
}
int find(int x)
{
if(fa[x]!=x)
{
int temp=fa[x];
fa[x]=find(temp);
sum[x]+=sum[temp];
}
return fa[x];
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init(n);
int ans=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&s);
a--;
int aa=find(a),bb=find(b);
if(aa==bb)
{
if(sum[b]-sum[a]!=s)ans++;
}
else
{
fa[bb]=aa;
sum[bb]=sum[a]-sum[b]+s;
}
}
printf("%d\n",ans);
}
return 0;
}