很经典的题目,而且是标准的线段树增加lazy标志的入门题目。
做了好久线段树,果然是practice makes perfect, 这次很畅快,打完一次性AC了。
标志的线段树函数。
主要是:
更新的时候只更新到需要的节点,然后最后的时候一次性把所以节点都更新完毕。
这也是线段树常用的技术。
#include <stdio.h> const int SIZE = 100005; struct Node { bool lazy; int metal; }; const int TREESIZE = SIZE + (SIZE<<1); Node segTree[TREESIZE]; inline int lChild(int rt) { return rt<<1;} inline int rChild(int rt) { return rt<<1|1;} void build(int l, int r, int rt) { segTree[rt].lazy = 0; segTree[rt].metal = 1; if (l == r) return ;//不要忘记这里返回! int m = l + ((r-l)>>1); build(l, m, lChild(rt)); build(m+1, r, rChild(rt)); } inline void pushDown(int rt) { if (segTree[rt].lazy) { segTree[rt].lazy = false;//别忘记了 int id = lChild(rt); segTree[id].lazy = true; segTree[id].metal = segTree[rt].metal; id = rChild(rt); segTree[id].lazy = true; segTree[id].metal = segTree[rt].metal; } } void update(int metal,const int L, const int R, int l, int r, int rt) { if (L <= l && r <= R) { segTree[rt].lazy = true; segTree[rt].metal = metal; return; } if (r < L || R < l) return ; pushDown(rt); int m = l + ((r-l)>>1); update(metal, L, R, l, m, lChild(rt)); update(metal, L, R, m+1, r, rChild(rt)); } void query(int l, int r, int rt, int &res) { if (l == r) { res += segTree[rt].metal; return ; } pushDown(rt); int m = l + ((r-l)>>1); query(l, m, lChild(rt), res); query(m+1, r, rChild(rt), res); } int main() { int T, N, Q, x, y, z; scanf("%d", &T); for (int t = 1; t <= T; t++) { scanf("%d", &N); build(1, N, 1); scanf("%d", &Q); while (Q--) { scanf("%d %d %d", &x, &y, &z); update(z, x, y, 1, N, 1); } int res = 0; query(1, N, 1, res); printf("Case %d: The total value of the hook is %d.\n", t, res); } return 0; }
HDU 1698 Just a Hook 线段树解法
时间: 2024-12-27 19:27:28