题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038
题意:给出区间[1,n],下面有m组数据,l r v区间[l,r]之和为v,每输入一组数据,判断此组条件是否与前面冲突 ,最后输出与前面冲突的数据的个数.
比如 [1 5]区间和为100 然后后面给出区间[1,2]的和为 200 那肯定就是有问题的了。
极力推荐这位大牛的博客:http://blog.csdn.net/niushuai666/article/details/6981689
这题让我学到了很多,特别是关于向量偏移,可以直接找到根节点与子节点的关系
aaarticlea/png;base64,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" alt="" width="262" height="220" />
这题我们利用一个sum[]数组保存从某点到其祖先节点距离。
1.从上图我们可以看出,当roota!=rootb时 如果将roota并入rootb,那么是不是 roota->rootb = b->rootb - b->roota
然后我们可以知道 b->roota = a->roota - a->b
所以最后可以推出 roota ->rootb = b->rootb + a->b - a->roota
而roota的根节点是rootb,所以 roota->rootb = sum[roota]
然后依次推出得到 sum[roota] = -sum[a]+sum[b]+v (这里的a要说明一下由于是区间 [a,b] ,[a,b] = [root,b]-[root,a-1],所以a要减一)
aaarticlea/png;base64,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" alt="" width="210" height="178" />
2.如果roota==rootb 是不是 a和b的根节点已经相同了?所以我们只要验证 a->b是否与题中的长度一致了。
所以 a->b = a->root - b->root
然后得到表达式 v = sum[a]-sum[b] (一定要记住这里的sum都是相对于根节点的,sum的更新在路径压缩的时候更新了)
这样说是不是懂了向量偏移的思想呢??
下面上代码:
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int N =;
int father[N];
int sum[N]; ///记录当前结点到根结点的距离 int _find(int x){
if(x!=father[x]){
int t = father[x];
father[x] = _find(father[x]);
sum[x]+=sum[t];
}
return father[x];
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=;i<=n;i++){
father[i] = i;
sum[i] = ;
}
int ans = ;
while(m--){
int a,b,v;
scanf("%d%d%d",&a,&b,&v);
a--;
int roota = _find(a);
int rootb = _find(b);
if(roota==rootb){
if(sum[a]-sum[b]!=v) ans++; ///精华部分1
}
else{
father[roota] = rootb;
sum[roota] = -sum[a]+sum[b]+v; ///精华部分2
}
}
printf("%d\n",ans);
}
return ;
}