题目大意:T组测试,每组n个钩子,起初每个钩子价值为1,然后m组更新,每次把[a,b]区域内的钩子的每个价值都更新为c。
然后让你求所有钩子价值的总和。
单点更新做了几道了,感觉想法越来越神,于是先换换口味。第一次写成段更新的题,看着两种风格的模版以及自己的习惯改来改去,虽然花了不少时间。但改的过程中也对懒惰标记加深了体会,看来多动脑更得勤动手。
存个自己的代码习惯
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL(x) (x << 1)
#define RR(x) (x << 1 | 1)
#define MID(x, y) (x + ((y - x) >> 1))
#define lson l, mid, LL(t)
#define rson mid + 1, r, RR(t)
#define MAX 100005
int n, m, t;
class segment_tree {
public:
int tree[MAX * 4];
int col[MAX * 4];
int point[MAX * 4];//记录该节点下方左右子节点各有多少个节点
void build(int l, int r, int t) {
tree[t] = r - l + 1;
col[t] = 1;
if(l == r) {
point[t] = 1;
} else {
int mid = MID(l, r);
build(lson);
build(rson);
point[t] = point[LL(t)] + point[RR(t)];
}
}
void PushUp(int t) {
tree[t] = tree[LL(t)] + tree[RR(t)];
}
void PushDown(int t) {
if(col[t]) {
col[LL(t)] = col[RR(t)] = col[t];
tree[LL(t)] = point[LL(t)] * col[LL(t)];
tree[RR(t)] = point[RR(t)] * col[RR(t)];
col[t] = 0;
}
}
void update(int st, int ed, int l, int r, int t, int w) {
if(st <= l && r <= ed) {
col[t] = w;
tree[t] = (r - l + 1) * col[t];
return ;
}
PushDown(t);
int mid = MID(l, r);
if(st <= mid) update(st, ed, lson, w);
if(ed > mid) update(st, ed, rson, w);
PushUp(t);
}
} seg;
int main() {
while(~scanf("%d", &t)) {
int t_cnt = 0;
while(t--) {
scanf("%d%d", &n, &m);
seg.build(1, n, 1);
while(m--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
seg.update(a, b, 1, n, 1, c);
}
printf("Case %d: The total value of the hook is %d.\n",++t_cnt,seg.tree[1]);
}
}
return 0;
}