题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698
题意:n个价值为1的棍子,按照输入把区间[x,y]的棍子变成z.问经过q操作后,总价值是多少。
线段树成段更新的裸题,学习了lazy的用法。区间更新时先更新到他的下一层左右节点,再往下就等到用到左右节点的时候再往下更新,用一个lazy数组配合pushDown实现。
注意:lazy为什么有时累加,有时直接赋值。累加是因为每次update是叠加的,而这题从1------2-------3--------1,
lazy是1,因为效果不叠加,只考虑最后一次修改。
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include <queue>
using namespace std;
const int maxn = 100005;
const int oo = 0xfffffff;
#define L_CHILD rt<<1, begin, mid
#define R_CHILD rt<<1|1, mid + 1, end
int segTree[maxn<<2];
int lazy[maxn<<2];
int n;
void pushUp(int rt) {
segTree[rt] = segTree[rt<<1] + segTree[rt<<1|1];
}
void pushDown(int rt, int begin, int end) {
if(lazy[rt]) {
int mid = begin + end >> 1;
lazy[rt<<1] = lazy[rt];
lazy[rt<<1|1] = lazy[rt];
segTree[rt<<1] = (mid - begin + 1) * lazy[rt]; // [begin, mid]
segTree[rt<<1|1] = (end - mid) * lazy[rt]; // [mid + 1, end]
lazy[rt] = 0;
}
}
void build(int rt, int begin, int end) {
lazy[rt] = 0; // 开始无标记
if(begin == end) {
segTree[rt] = 1;
return ;
}
int mid = begin + end >> 1;
build(L_CHILD);
build(R_CHILD);
pushUp(rt);
}
void update(int rt, int begin, int end, int left, int right, int val) {
if(left > end || right < begin) {
// 网上有很多种写法,个人习惯这样写简洁,省去下面的if。
return ;
}
if(left <= begin && end <= right) {
lazy[rt] = val;
segTree[rt] = val * (end - begin + 1);
return ; // 不更新[begin,end]的子区间对应的根节点了
}
pushDown(rt, begin, end); // 更新左右节点而已
int mid = begin + end >> 1;
update(L_CHILD, left, right, val);
update(R_CHILD, left, right, val);
pushUp(rt);
}
int query(int rt, int begin, int end, int left, int right) {
if(left > end || right < begin) {
return 0;
}
if(left <= begin && end <= right) {
return segTree[rt];
}
pushDown(rt, begin, end);
int mid = begin + end >> 1;
return query(L_CHILD, left, right) + query(R_CHILD, left, right);
}
int main() {
int t, cas = 0, q;
int x, y, val;
scanf("%d", &t);
while (t --) {
scanf("%d%d", &n, &q);
build(1, 1, n);
while (q--) {
scanf("%d%d%d", &x, &y, &val);
update(1, 1, n, x, y, val);
}
printf("Case %d: The total value of the hook is %d.\n", ++cas, segTree[1]);
}
return 0;
}