一、内容
题意:给定一个区间,初始值都是1,和几组询问,每次询问将一段区间修改成某个值,最后求所有区间的和。
二、思路
- 用一个数组sum进行lazy标记和下放就可以了, 如果这个区间有多个数那么这个区间sum[id] = -1, 若这个区间全部是一个相同的数那么sum[id]=相同数。
- 进行pushdown()的时候,只需要讲左右儿子区间赋值为sum[id], sum[id] = -1即可
- 最后query() 统计所有区间的和
三、代码
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 5;
int t, x, y, z, n, q, sum[maxn << 2], ans;
void pushdown(int id) {
if (sum[id] == -1) return;
sum[id << 1] = sum[id << 1 | 1] = sum[id];
sum[id] = -1;
}
void update(int id, int l, int r, int x, int y, int z) {
if (x <= l && r <= y) {
sum[id] = z;
return;
}
pushdown(id);
int mid = (l + r) >> 1;
if (x <= mid) {
update(id << 1, l, mid, x, y ,z);
}
if (y > mid) {
update(id << 1 | 1, mid + 1, r, x, y, z);
}
}
void query(int id, int l, int r) {
if (sum[id] != -1) {
ans += sum[id] * (r - l + 1);
return;
}
int mid = (l + r) >> 1;
query(id << 1, l, mid);
query(id << 1 | 1, mid + 1, r);
}
int main() {
scanf("%d", &t);
for (int size = 1; size <= t; size++) {
memset(sum, -1, sizeof(sum));
scanf("%d%d", &n, &q);
sum[1] = 1; //初始全部都是铜
for (int i = 1; i <= q; i++) {
scanf("%d%d%d", &x, &y, &z);
update(1, 1, n, x, y, z);
}
ans = 0;
query(1, 1, n);
printf("Case %d: The total value of the hook is %d.\n", size, ans);
}
return 0;
}