题目背景
原题:HDU3038
题目描述
有一个长度为 NN 的整数序列,其中的数未知;但有 MM 条信息,每条信息描述该序列中区间 [L,R][L,R] 的和为 VV。
然而,其中有一些信息与在它之前输入的某些信息存在冲突(即能推出矛盾)。请找出并忽略这些信息。问有多少条这样的的信息?
输入格式
第 11 行输入两个整数 NN 和 MM,表示有 NN 个整数,MM 条信息。第 2∼M+12∼M+1 行中,每行输入 33 个整数 Li,Ri,ViLi,Ri,Vi,表示 [Li,Ri][Li,Ri] 区间和为 ViVi。
输出格式
一行一个整数,表示有误信息的条数。
输入数据 1
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
输出数据 1
1
数据范围
1≤N≤2×1051≤N≤2×105
1≤M≤400001≤M≤40000
0<Li≤Ri≤N0<Li≤Ri≤N
保证任何子序列的和不超过 3232 位整数的范围。
题解
#include<bits/stdc++.h>
using namespace std;
const int maxn=400000+2000;
int par[maxn],val[maxn];
int n,ans;
int find(int x)
{
int k=par[x];
if(x!=k)
{
par[x]=find(k);
val[x]+=val[k];
}
return par[x];
}
void Union(int x,int y)
{
par[find(x)]=find(y);
}
void init()
{
ans=0;
for(int i=0;i<=n;i++)
{
val[i]=0;
par[i]=i;
}
}
int main()
{
int m,a,b,c;
//freopen("D.txt","r",stdin);
while(scanf("%d %d",&n,&m)!=EOF)
{
//cout<<maxn<<endl;
init();
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&a,&b,&c);
a--;
//cout<<a<<b<<c<<endl;
int L1=find(a),L2=find(b);
if(L1==L2&&val[a]+c!=val[b])
{
//cout<<L1<<L2<<endl;
ans++;
}
else if(L1<L2)
{
par[L2]=L1;
val[L2]=val[a]-val[b]+c;
}
else if(L1>L2)
{
par[L1]=L2;
val[L1]=val[b]-val[a]-c;
}
}
printf("%d\n",ans);
}
return 0;
}
//so 简单