[HDU 3038] How Many Answers Are Wrong

题目传送-HDU3038

题意:

你有一个长度为\(n\)的序列\(A\),其中元素可正可负,但你不知道具体值
给你m个三元组\((a,b,c)\),表示\(\sum_{i=a}^ba_i=c\)
问有多少个是错的,即与之前的限制矛盾的
如果一个限制被判为不合法,则其不产生影响
\(n \le 200000,m \le 40000\)

题解:

很显然的带权并查集。
定义\(sum_i=\sum_{j=1}^i a_j\)
则一个限制\((a,b,c)\)等同于\(sum_b-sum_{a-1}=c\)
以这个作为并查集权值,搞一搞就行了

过程:

注意式子不要推错了,前后关系和正负号要对应

代码:

const int N=200010;
int n,m;
int val[N],fat[N];
int father(int x) {
    if(x==fat[x]) return x;
    int f=fat[x]; fat[x]=father(fat[x]);
    val[x]=val[x]+val[f];
    return fat[x];
}
signed main() {
    while(scanf("%d %d",&n,&m)!=EOF) {
        int ans=0;
        for(int i=1;i<=n;i++) fat[i]=i,val[i]=0;
        for(int i=1;i<=m;i++) {
            int x,y,w;
            read(x); read(y); read(w); --x;
            int fx=father(x),fy=father(y);
            if(fx==fy) {
                ans+=(val[y]-val[x]!=w);
            } else {
                fat[fy]=fx;
                val[fy]=w+val[x]-val[y];
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

用时:20min

转载于:https://www.cnblogs.com/functionendless/p/9463990.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值