HDU - 3038
https://vjudge.net/problem/HDU-3038#author=0
给出一个区间的长度 N,及 M 个子区间和, 形如:x y z, 表示
子区间 [x, y] 的和为 z
如果一个“子区间和”与前面的“子区间和”冲突,即为错误(而且这个“子区间和”将在接下来的判断中被忽略)。
求总错误个数。
Input
有多组数据。
每组数据第一行两个整数N M (1 <= N <= 200000, 1 <= M <= 40000),
接下来每行有 M 对关系 x y z;
注:可以认为 z 为32位整型。
Output
错误个数。
Sample Input
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
Sample Output
1
带权并查集板题
若更新代表点f2的代表点为f1,
则 d[f2] = 差量(即d[x1]-d[x2]) + 边权
#include<iostream> #include<cstdio> #define ri register int #define u int namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using opt::in; #define NN 200005 namespace cas { u fa[NN],d[NN]; u getfa(const u &x){ if(fa[x]^x){ u _t(fa[x]); fa[x]=getfa(fa[x]); d[x]+=d[_t]; } return fa[x]; } inline void pri(const u &N){ for(ri i(0);i<=N;++i) fa[i]=i,d[i]=0; } } namespace mainstay { u N,M; using namespace cas; inline void solve(){ while(~scanf("%d%d",&N,&M)){ u ans(0); pri(N); for(ri i(1);i<=M;++i){ u _l(in()-1),_r(in()),_x(in()); u fl(getfa(_l)),fr(getfa(_r)); if(fl^fr){ fa[fr]=fl,d[fr]=d[_l]-d[_r]+_x; } else{ if((d[_r]-d[_l])^_x) ++ans; } } printf("%d\n",ans); } } } int main() { //freopen("x.txt","r",stdin); std::ios::sync_with_stdio(false); mainstay::solve(); }