题意:输出T是case数,然后输入N,代表1~N 默认的value是1,然后输入区间[a,b] 和 value c ,把 a~b 的价值更新为c ,最后输出1~N的价值即可
思路:线段树 成段更新 最后输出线段树的sum[1]就行。
#include<iostream>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r ,rt << 1 | 1
const int maxn = 100005;
int sum[maxn<<2];
int add[maxn<<2];//懒惰标记
void PushUP(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m) {//节点标号和区间长度
if (add[rt]) {
printf("rrt==%d\n",rt);
add[rt<<1] = add[rt];
add[rt<<1|1] = add[rt];
sum[rt<<1] = add[rt] * (m - (m >> 1));//例如[1,5] 的子节点是 [1,3]和[4,5] ,除以二是向下取整,左节点的长度 >= 右节点的长度所以这样
sum[rt<<1|1] = add[rt] * (m >> 1);
add[rt] = 0;
}
}
void build(int l,int r,int rt) {
add[rt] = 0;
sum[rt] = 1;
if (l == r) {
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUP(rt);
}
void update(int L,int R,int val,int l,int r,int rt) {
if (L <= l && R >= r) {
add[rt] = val;
sum[rt] = val * (r - l + 1);
printf("rt=%d\n",rt);
return ;
}
int m = (l + r) >> 1;
PushDown(rt , r - l + 1);
if (m >= L) update(L , R , val , lson);
if (m < R) update(L , R , val , rson);
PushUP(rt);
}
int main() {
int T , n , m;
scanf("%d",&T);
for (int i = 1 ; i <= T ; i ++) {
scanf("%d%d",&n,&m);
build(1 , n , 1);
while (m --) {
int a , b , c;
scanf("%d%d%d",&a,&b,&c);
update(a , b , c , 1 , n , 1);
}
printf("Case %d: The total value of the hook is %d.\n",i,sum[1]);
}
}