HDU 3038 How Many Answers Are Wrong 带权并查集

TT and FF are ... friends. Uh... very very good friends -________-b

FF is a bad boy, he is always wooing TT to play the following game with him. This is a very humdrum game. To begin with, TT should write down a sequence of integers-_-!!(bored).

Then, FF can choose a continuous subsequence from it(for example the subsequence from the third to the fifth integer inclusively). After that, FF will ask TT what the sum of the subsequence he chose is. The next, TT will answer FF's question. Then, FF can redo this process. In the end, FF must work out the entire sequence of integers.

Boring~~Boring~~a very very boring game!!! TT doesn't want to play with FF at all. To punish FF, she often tells FF the wrong answers on purpose.

The bad boy is not a fool man. FF detects some answers are incompatible. Of course, these contradictions make it difficult to calculate the sequence.

However, TT is a nice and lovely girl. She doesn't have the heart to be hard on FF. To save time, she guarantees that the answers are all right if there is no logical mistakes indeed.

What's more, if FF finds an answer to be wrong, he will ignore it when judging next answers.

But there will be so many questions that poor FF can't make sure whether the current answer is right or wrong in a moment. So he decides to write a program to help him with this matter. The program will receive a series of questions from FF together with the answers FF has received from TT. The aim of this program is to find how many answers are wrong. Only by ignoring the wrong answers can FF work out the entire sequence of integers. Poor FF has no time to do this job. And now he is asking for your help~(Why asking trouble for himself~~Bad boy)
Input
Line 1: Two integers, N and M (1 <= N <= 200000, 1 <= M <= 40000). Means TT wrote N integers and FF asked her M questions.

Line 2..M+1: Line i+1 contains three integer: Ai, Bi and Si. Means TT answered FF that the sum from Ai to Bi is Si. It's guaranteed that 0 < Ai <= Bi <= N.

You can assume that any sum of subsequence is fit in 32-bit integer.
Output
A single line with a integer denotes how many answers are wrong.
Sample Input
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
Sample Output
1
这个题不太会说怎么做的,因为我还是不是非常理解他题目的意思。大概就是在没有非常非常明显的错误的情况下,让你发现错误。QAQ。
 
 
 
 
例如 在[1,9]的区间和为10,[2,9]的区间和为10086,显然这是明显的错误,而题目不会认为这是错误的。因为不存在非常非常明显的错误
 
 
 
 
如果给你一个区间,我么就把他的两端点并起来,表示他们是有关系的。他们的关系就是[a,b]之间元素的和,如果再来一个集合,[b,d],那么b与b是有关系的,以为之前说了,a与b有关系
那么可以知道a与d是有关系的,这就是并查集的原理。当你输入两个元素有相同的boss节点,那么就可以确定他们之间的关系与你所给出的关系是不是一样的,如果是一样的,
就说明这个区间和没毛病,如果不相等就有毛病
那么我们具体怎么来找他们之间的关系呢。现在你有两个关系(父亲节点是a,j的区间和)[a,f]   [j,n],其中[a,f]中有一个元素是b,[j,n]中
有一个元素是k,现在给你这两个元素的所决定区间的和T,你会发现什么?
我们发现,如果知道了这两个的元素决定的区间和,我么就可以确定[a,j]的区间和。
不妨设某个节点x与他boss节点的关系是rale[x],根据我们学过的初中数学知识可以知道。[a,j]的所确定的区间和就是rale[b]+T-rale[j]
有了这个关系这个题基本就做出来了。
下面说说初始化。自己与自己所确定的区间和一定是0.
所以有下面的初始化条件
        for(int i=0;i<=n;i++)
        {
            rale[i]=0;
            pre[i]=i;
        }
然后说一下节点关系的传递与压缩
由于是和的形式,传递的关系肯定是前一个节点的rale加后一个节点的rale,就这么传递下去,我们为什么要传递,传递就是为了压缩后关系的正确定!
压缩为了什么?为了效率,为了更方便的查找,如果不压缩你每次都要从叶节点走到根节点然后找到关系!
下面是压缩+关系传递
int findboss(int x)
{
    if(x==pre[x])
        return x;
    else
    {
        int t=pre[x];
        pre[x]=findboss(pre[x]);
        rale[x]=rale[x]+rale[t];
        return pre[x];
    }
}
哦 对了 还有一点,由于这是一个区间查询,你要把u-1来把节点空出来,比如给你一个6 6,如果不空出来里面的值就是0,可能就是错了
下面ac代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int pre[233333];
int rale[233333];
int findboss(int x)
{
    if(x==pre[x])
        return x;
    else
    {
        int t=pre[x];
        pre[x]=findboss(pre[x]);
        rale[x]=rale[x]+rale[t];
        return pre[x];
    }
}
int main()
{

    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int ans=0;
        for(int i=0;i<=n;i++)
        {
            rale[i]=0;
            pre[i]=i;
        }
        while(m--)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            u--;
            int aa=findboss(u),bb=findboss(v);
            if(aa==bb)
            {
                if(rale[v]-rale[u]!=w)
                    ans++;

            }
            else
            {
                pre[bb]=aa;
                rale[bb]=w+rale[u]-rale[v];
            }

        }
        printf("%d\n",ans);
    }
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值