Description
给出一个长度为 N 的区间,以及 M 个子区间和
子区间 [x, y] 的和为 z
如果出现了当前的“子区间和”与之前出现过的“子区间和”发生冲突的情况,则我们判断是当前的“子区间和”产生了错误,并且我们将忽略掉当前的“子区间和”
请算一下出现错误的“子区间和”一共有多少个
Input
第一行两个整数N M (1 <= N <= 200000, 1 <= M <= 40000)
接下来 M 行,每行都是一个子区间和关系 x y z;
Output
出现错误的“子区间和”的总个数
Sample Input Copy
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
Sample Output Copy
1
HINT
仔细看看样列——by小李
分析:
通过哦样例可以得出,每个区间代表特殊的值,当输入区间的值不符合原有的值则视为‘错误的’子区间和。
关键代码:
cin>>x>>y>>z;
x--;
int a = find_pre(x);
int b = find_pre(y);
if(a==b)
{
if(value[x]-value[y]!=z)//判断
{
ans++;
}
}
else if(a>b)
{
pre[b] = a;
value[b]= value[x]-value[y]-z;//权值改变
}
}
else
{
pre[a] = b;
value[a]= value[y]-value[x]+z;//权值改变
}
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(false); cin.tie(NULL);
const int N = 2e5+10;
//const int M = 5e2+10;
int pre[N];
int value[N];
int find_pre(int x)//路径压缩找父节点
{
if(x!=pre[x])
{
int t=pre[x];
pre[x]=find_pre(pre[x]);
value[x]+=value[t];
}
else
return pre[x];
return pre[x];
}
int main()
{
int n,m,x,y,z;
int ans=0;
cin>>n>>m;
for(int i=0; i<=n; i++)
{
pre[i]=i;
value[i]=0;
}
while(m--)
{
cin>>x>>y>>z;
x--;
int a = find_pre(x);
int b = find_pre(y);
if(a==b)
{
if(value[x]-value[y]!=z)
{
ans++;
}
}
else if(a>b)
{
pre[b] = a;
value[b]= value[x]-value[y]-z;
}
else
{
pre[a] = b;
value[a]= value[y]-value[x]+z;
}
}
cout<<ans<<endl;
return 0;
}