成段更新(通常這對初學者來說是一道坎),需要用到延遲標記(或者說懶惰標記),簡單來說就是每次更新的時候不要更新到底,用延遲標記使得更新延遲到下次需要更新or詢問到的時候
#include <iostream>using namespace std;#define lson l, m, rt << 1#define rson m+1, r, rt << 1 | 1const int maxn = 111111;int h, w, n;int col[maxn << 2];int sum[maxn << 2];void pushUp(int rt) //更新當前結點{sum[rt] = sum[rt<<1] + sum[rt << 1 | 1];}void pushDown(int rt, int num) //更新子結點{if(col[rt]){col[rt << 1] = col[rt << 1 | 1] = col[rt];sum[rt << 1] = (num - (num >> 1)) * col[rt];sum[rt << 1 | 1] = (num >> 1) * col[rt];col[rt] = 0;}}void build(int l, int r, int rt){col[rt] = 0;sum[rt] = 1;if(l == r) return;int m = (l + r) >> 1;build(lson);build(rson);pushUp(rt); //子樹遞迴求解後,可以求和等到根的值}void update(int L, int R, int c, int l, int r, int rt){if(L <= l && r <= R){col[rt] = c;sum[rt] = c * (r - l+ 1);return;}pushDown(rt, r - l + 1); //先將子節點先更新int m =(l + r) >> 1;if(L <= m) update(L, R, c, lson);if(R > m) update(L, R, c, rson);pushUp(rt); //更新當前結點(上面兩句已經將左右子樹的值更新)}int main(){int t, n, m;scanf("%d", &t);for(int cas = 1; cas <= t; cas++){scanf("%d%d", &n, &m);build(1, n, 1);while(m--){int a, b, c;scanf("%d %d %d", &a, &b, &c);update(a, b, c, 1, n, 1);}printf("Case %d: The total value of the hook is %d.\n", cas, sum[1]);}return 0;}