hdu3038

How Many Answers Are Wrong

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6981    Accepted Submission(s): 2584


Problem Description
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
  题意是两个小朋友在玩游戏,甲在纸上写了n个数字,乙询问m次[ai,b[i]]这个区间里的数字和是多少,然后对方回答是si,不过甲比较调皮会骗人,有时候的回答是假的。问你他说了几句假话,(以先说的为准)。
这道题一开始就想用线段树做,结果根本想不出来,看了一些discuss说是用并查集写,惊呆了。
然后搜索种类并查集,学习了一些姿势水平(poj1182食物链,很好很逻辑的并查集题目。)
/*我们定义一个节点node
    node[i].fa 代表i的父亲节点
    node[i].relation 等于 区间【i+1 , node[i].fa】的值的和
    我们初始化为node[i].fa = i ,node[i].relation = 0(这里挺重要的,因为我们一开始不知道每个数字的值,所以只能默认sum[i + 1, i ] ==0)
    对于每次输入的l,r ,我们先把l- 1 ,然后分别求l,r的根,(注意求根时要进行值的转移)
    如果根不相等,说明没有合并过,也就是这个区间还没有关系不存在真假的问题
    但是要进行合并 合并公式在Union中,画个图挺好推的
    如果根相同,那么说明这个区间可以得到正确的关系,如果node[l].relation - node[r].relatoin != sum ,那么就是假话;
*/
#pragma GCC optimize ("03")
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<time.h>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<iostream>
using namespace std;
#define  LONG long long
const int   INF=0x3f3f3f3f;
const int MOD=1e9+7;
const double PI=acos(-1.0);
#define clrI(x) memset(x,-1,sizeof(x))
#define clr0(x) memset(x,0,sizeof x)
#define clr1(x) memset(x,INF,sizeof x)
#define clr2(x) memset(x,-INF,sizeof x)
#define EPS 1e-10
struct Node
{
    int   fa , id ;
    LONG  relation;
}node[250000];
void Init()
{
    for(int i = 0; i <= 210000 ; ++ i)
    {
        node[i].fa = i ;
        node[i].id = i ;
        node[i].relation = 0;
    }
}
int findfa(int i )
{
    if(i == node[i].fa )return i;
    else
    {
        int root = node[i].fa ;
        node[i].fa = findfa(root ); //注意应该先找到根节点,同时保证父亲节点的relation是正确的 才可以给当前的node[i]计算relation值;
        node[i].relation = node[i].relation + node[root].relation ;
        return node[i].fa ;
    }
}
void Union(int l ,int r , int ql , int qr  , LONG val)
{
    if( ql < qr )
    {
        node[ql].fa = qr;
        node[ql].relation = node[r].relation + val - node[l].relation ;
    }
    else
    {
        node[qr].fa = ql;
        node[qr].relation = -val + node[l].relation - node[r].relation;
    }
}
int main()
{
    int n , m ;
    while(cin>>n>>m)
    {
        Init();
        int l , r ;
        LONG sum;
        int ans = 0 ;
        for(int  i =1; i<= m ;++ i)
        {
            scanf("%d%d%lld",&l,&r,&sum);
            l -- ;
            int r1 = findfa(l);
            int r2 = findfa(r);
            if(r1 != r2 )
                Union( l   ,r , r1 , r2 , sum );
            else
            {
                if(node[l].relation - node[r].relation != sum)
                {
                    ans ++ ;
                }
            }
        }
        cout<<ans<<endl;
    }
}

  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值