HDOJ1698 Just a Hook 線段樹區間更新
阿新 • • 發佈:2019-01-30
分析:一道比較裸的線段樹區間更新題,對比正常的線段樹問題,主要是每一次都對節點進行直接賦值,另外注意初始值為1。
程式碼:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 100005; int m, n, q, x, y, z; struct Node { int left, right, value; }; Node nodes[maxn << 2]; int add[maxn << 2]; void PushUp(int i) { nodes[i].value = nodes[i << 1].value + nodes[i << 1 | 1].value; } void PushDown(int i) { if(add[i] != 0) { int len = (nodes[i].right - nodes[i].left + 1); add[i << 1] = add[i]; add[i << 1 | 1] = add[i]; nodes[i << 1].value = add[i] * (len - (len >> 1)); nodes[i << 1 | 1].value = add[i] * (len >> 1); add[i] = 0; } } void build(int i, int left, int right) { nodes[i].left = left; nodes[i].right = right; nodes[i].value = 0; if(left == right) { nodes[i].value = 1; return; } int mid = (left + right) >> 1; build(i << 1, left, mid); build(i << 1 | 1, mid + 1, right); PushUp(i); } void update(int i, int left, int right, int value) { if(nodes[i].left == left && nodes[i].right == right) { add[i] = value; nodes[i].value = value * (right - left + 1); return; } if(nodes[i].left == nodes[i].right) { return; } PushDown(i); int mid = (nodes[i].left + nodes[i].right) >> 1; if(right <= mid) { update(i << 1, left, right,value); } else { if(left >= mid + 1) { update(i << 1 | 1, left, right, value); } else { update(i << 1, left, mid, value); update(i << 1 | 1, mid + 1, right, value); } } PushUp(i); } int query(int i, int left, int right) { if(nodes[i].left == left && nodes[i].right == right) { return nodes[i].value; } PushDown(i); int mid = (nodes[i].left + nodes[i].right) >> 1; if(right <= mid) { return query(i << 1, left, right); } else { if(left >= mid + 1) { return query(i << 1 | 1, left, right); } else { return query(i << 1, left, mid) + query(i << 1 | 1, mid + 1, right); } } } int main() { scanf("%d", &m); for(int kase = 1; kase <= m; kase++) { memset(add, 0, sizeof(add)); memset(nodes, 0, sizeof(nodes)); scanf("%d", &n); scanf("%d", &q); build(1, 1, n); for(int i = 1; i <= q; i++) { scanf("%d%d%d", &x, &y, &z); update(1, x, y, z); } printf("Case %d: The total value of the hook is %d.\n", kase, query(1, 1, n)); } return 0; }