HDU 1698 Just a Hook——區間更新的線段樹
阿新 • • 發佈:2018-12-30
題意:一開始有n個1組成的數列,執行q此操作,每次操作給出x y z,表示把區間【x,y】內的所有數變成z,執行完q此操作後求整個數列的和
思路:直接套用區間更新線段樹的模板,進行簡單的更新值與求和操作
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 10; int T, n, q, date[maxn], segTree[maxn<<2], lazy[maxn<<2]; void init() { for (int i = 1; i <= n; i++) { date[i] = 1; } for (int i = 1; i <= n<<2; i++) { segTree[i] = 0; lazy[i] = 0; } } void pushup(int root) { segTree[root] = segTree[root<<1] + segTree[root<<1|1]; } void pushdown(int root, int cntL, int cntR) { if (lazy[root]) { lazy[root<<1] = lazy[root]; lazy[root<<1|1] = lazy[root]; segTree[root<<1] = lazy[root] * cntL; segTree[root<<1|1] = lazy[root] * cntR; lazy[root] = 0; } } void build(int L, int R, int root) { if (L == R) { segTree[root] = date[L]; return; } int mid = (L + R)>>1; build(L, mid, root<<1); build(mid + 1, R, root<<1|1); pushup(root); } void update_interval(int L, int R, int root, int uL, int uR, int val) { if (uL <= L && R <= uR) { segTree[root] = val * (R - L + 1); lazy[root] = val; return; } int mid = (L + R)>>1; pushdown(root, mid - L + 1, R - mid); if (uL <= mid) { update_interval(L, mid, root<<1, uL, uR, val); } if (uR > mid) { update_interval(mid + 1, R, root<<1|1, uL, uR, val); } pushup(root); } int query(int L, int R, int root, int qL, int qR) { if (qL <= L && R <= qR) { return segTree[root]; } int mid = (L + R)>>1; pushdown(root, mid - L + 1, R - mid); int ans = 0; if (qL <= mid) { ans += query(L, mid, root<<1, qL, qR); } if (qR > mid) { ans += query(mid + 1, R, root<<1|1, qL, qR); } return ans; } int main() { scanf("%d", &T); for (int kase = 1; kase <= T; kase++) { scanf("%d%d", &n, &q); init(); build(1, n, 1); while (q--) { int a, b, c; scanf("%d %d %d", &a, &b, &c); update_interval(1, n, 1, a, b, c); } printf("Case %d: The total value of the hook is %d.\n", kase, query(1, n, 1, 1, n)); } return 0; }