/* Author: ACb0y Date: 2010-9-07 Type: seg_tree ProblemId: hdu 1698 Result: 2928262 2010-09-07 16:48:47 Accepted 1698 484MS 4324K 1762 B C++ ACb0y */ #include <iostream> using namespace std; //节点信息 struct node { //区间 int left; int right; //是否被全部涂成一个颜色 int cover; //区间所涂的颜色 int color; }; //存储线段树数组(完全二叉树) node seg_tree[300000]; //建树 void buildTree(int left, int right, int loc) { seg_tree[loc].left = left; seg_tree[loc].right = right; seg_tree[loc].cover = seg_tree[loc].color = 1; //叶子节点返回 if (left == right) return ; int mid = (left + right) >> 1; //建左子树 buildTree(left, mid, loc * 2); //建右子树 buildTree(mid + 1, right, loc * 2 + 1); } //更新树 void updateTree(int left, int right, int value, int loc) { int LL = loc * 2; int RR = loc * 2 + 1; //如何更新的区间刚好是某个子树的区间则直接更新。 if (seg_tree[loc].left == left && seg_tree[loc].right == right) { seg_tree[loc].cover = 1; seg_tree[loc].color = value; return ; } //如果树是被覆盖 if (seg_tree[loc].cover) { seg_tree[loc].cover = 0; seg_tree[LL].cover = seg_tree[RR].cover = 1; seg_tree[LL].color = seg_tree[RR].color = seg_tree[loc].color; } int mid = (seg_tree[loc].left + seg_tree[loc].right) / 2; //如果要更新的区间在左子树中则更新左子树 if (right <= mid) { updateTree(left, right, value, LL); } //如果要更新的区间在右子树,更新右子树 else if (mid < left) { updateTree(left, right, value, RR); } //要更新的区间为于左右子树之间,则同时更新左子树和右子树 else { updateTree(left, mid, value, LL); updateTree(mid + 1, right, value, RR); } } //查询区间和 int queryTotal(int loc) { //如果区间是被覆盖的直接计算。 if (seg_tree[loc].cover) { return (seg_tree[loc].right - seg_tree[loc].left + 1) * seg_tree[loc].color; } //否则求左右子树区间和的和。 else { return queryTotal(loc * 2) + queryTotal(loc * 2 + 1); } } int main() { int T; int cas = 1; #ifndef ONLINE_JUDGE freopen("1698.txt", "r", stdin); #endif scanf("%d", &T); while (T--) { int n, q; scanf("%d%d", &n, &q); buildTree(1, n, 1); for (int i = 0; i < q; i++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); updateTree(x, y, z, 1); } printf("Case %d: The total value of the hook is %d./n", cas++, queryTotal(1)); } return 0; }