标签:
http://acm.hdu.edu.cn/showproblem.php?pid=3038
题意:
给定数字个数N(A1,...,AN)和M句话,"l r s"代表下标[l,r]的数字之和为s
求出现冲突的句子数量
解法:
带权并查集
以区间右端为父节点,将l-1与r点合并
查询时进行路径压缩 sum[x] += sum[fa[x]]
合并时更新根节点的 sum[x] = sum[r] - sum[l] + s
则sum[x]表示[x+1, fa[x]]数字之和 (fa[x]<x时,sum[x]等于负的[A(fa[x]+1), Ax]数字之和)
同时判断同根节点的sum[l] - sum[r]是否等于给出的s
代码: 62MS 2236K
#include <cstdio> using namespace std; #define N 200001 int fa[N], sum[N], ans; void init(int n) { ans = 0; for (int i = 0; i <= n; i++) { fa[i] = i; sum[i] = 0; } } int findfa(int n) { if (n == fa[n]) { return n; } int t = findfa(fa[n]); sum[n] += sum[fa[n]]; return fa[n] = t; } bool unite(int l, int r, int s) { int x = findfa(l), y = findfa(r); if (x == y) { return (sum[l] - sum[r] != s); } fa[x] = y; sum[x] = sum[r] - sum[l] + s; return 0; } int main() { int n, q, l, r, s; while (~scanf("%d%d", &n, &q)) { init(n); for (int i = 0; i < q; i++) { scanf("%d%d%d", &l, &r, &s); ans += unite(l - 1, r, s); } printf("%d\n", ans); } return 0; }
HDU 3038 How Many Answers Are Wrong
标签:
原文地址:http://www.cnblogs.com/rsola/p/4266029.html