题意:(用通俗的语言描述)T组数据,每组数据第一行是一个数N,表示有N个数(初始都为1),第二行是一个数M,代表接下来有M组输入,每组输入三个数X,Y,Z,分别代表将[X,Y]区间的值改为Z,询问最后N个数的和。对于样例解释:初始的N为:1 1 1 1 1 1 1 1 1 1 sum = 10,操作之后:2 2 2 2 3 3 3 3 3 1 sum= 24,然后输出。
考察的是线段树的区间更新(延迟更新)。因为查询的是总区段的和,所以不需要进行查询操作了,具体请看代码:
//通常写法 904ms
#include <stdio.h>
const int maxn = 1e5+5;
struct Node{
int l, r;
int lazy;
int value;
int mid() {
return (l+r)>>1;
}
}node[maxn<<2];
void Pushdown(int i, int m) {
if(node[i].lazy) {
node[i<<1].lazy = node[i].lazy;
node[i<<1|1].lazy = node[i].lazy;
node[i<<1].value = node[i].lazy*(m-(m>>1));
node[i<<1|1].value = node[i].lazy*(m>>1);
node[i].lazy = 0;
}
return ;
}
void Build(int i, int l, int r) {
node[i].l = l;
node[i].r = r;
node[i].lazy = 1;
if(l == r) {
node[i].value = 1;
return ;
}
int m = (l+r)>>1;
Build(i<<1, l, m);
Build(i<<1|1, m+1, r);
node[i].value = node[i<<1].value+node[i<<1|1].value;
return ;
}
void Update(int i, int l, int r, int C) {
if(node[i].l == l && node[i].r == r) {
node[i].lazy = C;
node[i].value = C*(r-l+1);
return ;
}
if(node[i].l == node[i].r) return ;
Pushdown(i, node[i].r-node[i].l+1);
int m = node[i].mid();
if(r <= m) Update(i<<1, l, r, C);
else if(l > m) Update(i<<1|1, l, r, C);
else {
Update(i<<1, l, m, C);
Update(i<<1|1, m+1, r, C);
}
node[i].value = node[i<<1].value + node[i<<1|1].value;
return ;
}
int main() {
int T, N, M;
int X, Y, Z;
int Case = 1;
scanf("%d", &T);
while(T--) {
scanf("%d", &N);
Build(1, 1, N);
scanf("%d", &M);
while(M--) {
scanf("%d %d %d", &X, &Y, &Z);
Update(1, X, Y, Z);
}
printf("Case %d: The total value of the hook is %d.\n", Case++, node[1].value);
}
return 0;
}
//另一种写法 858ms
#include <stdio.h>
const int maxn = 1e5+5;
struct Node{
int lazy;
int value;
}node[maxn<<2];
void Pushdown(int i, int m) {
if(node[i].lazy) {
node[i<<1].lazy = node[i].lazy;
node[i<<1|1].lazy = node[i].lazy;
node[i<<1].value = node[i].lazy*(m-(m>>1));
node[i<<1|1].value = node[i].lazy*(m>>1);
node[i].lazy = 0;
}
return ;
}
void Build(int i, int l, int r) {
node[i].lazy = 0;
node[i].value = (r-l+1);
if(l == r) return ;
int m = (l+r)>>1;
Build(i<<1, l, m);
Build(i<<1|1, m+1, r);
}
void Update(int i, int l, int r, int left, int right, int C) {
if(l <= left && r >= right) {
node[i].lazy = C;
node[i].value = C*(right-left+1);
return ;
}
if(left == right) return ;
Pushdown(i, right-left+1);
int m = (left+right)/2;
if(l <= m) Update(i<<1, l, r, left, m, C);
if(r > m) Update(i<<1|1, l, r, m+1, right, C);
node[i].value = node[i<<1].value + node[i<<1|1].value;
return ;
}
int main() {
int T, N, M;
int X, Y, Z;
int Case = 1;
scanf("%d", &T);
while(T--) {
scanf("%d", &N);
Build(1, 1, N);
scanf("%d", &M);
while(M--) {
scanf("%d %d %d", &X, &Y, &Z);
Update(1, X, Y, 1, N, Z);
}
printf("Case %d: The total value of the hook is %d.\n", Case++, node[1].value);
}
return 0;
}