题目传送门:点我~~
成段更新(通常这对初学者来说是一道坎),需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新 or 询问到的时候.
#include <bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int MAXN = 100550; int sum[MAXN << 2]; int col[MAXN << 2]; void pushup(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } //中点也是属于左区间的,所以左区间>右区间 括号一定要加~要不然优先计算减法 void pushdown(int rt, int ans) { if (col[rt]) { col[rt << 1] = col[rt << 1 | 1] = col[rt]; sum[rt << 1] = (ans - (ans >> 1)) * col[rt]; sum[rt << 1 | 1] = (ans >> 1) * col[rt]; col[rt] = 0; } } void build(int l, int r, int rt) { col[rt] = 0; if (l == r) { sum[rt] = 1; return; } int m = (l + r) >> 1; build(lson); build(rson); pushup(rt); } void update(int L, int R, int res, int l, int r, int rt) { if (L <= l && r <= R) { //给当前点上标记 并且更新值 col[rt] = res; sum[rt] = (r - l + 1) * res; return; } pushdown(rt, r - l + 1); int m = (l + r) >> 1; if (L <= m) { update(L, R, res, lson); } if (R > m) { update(L, R, res, rson); } pushup(rt); } int main() { int t; scanf("%d", &t); int casee = 1; int n; while (t--) { scanf("%d", &n); build(1, n, 1); int q; scanf("%d", &q); int l, r, res; while (q--) { scanf("%d%d%d", &l, &r, &res); update(l, r, res, 1, n, 1); } printf("Case %d: The total value of the hook is %d.\n", casee++, sum[1]); } return 0; }
- 版权声明:本文基于《知识共享署名-相同方式共享 3.0 中国大陆许可协议》发布,转载请遵循本协议
- 文章链接:http://www.carlstedt.cn/archives/656 (转载时请注明本文出处及文章链接)
发表评论
快来吐槽一下吧!