第一次写线段树区间更新,一遍遍的错直到慢慢发现发现自己错在哪,额。。。
关键要处理好add[root]下方的时机,一定要清楚的保证add为0时该段区间已经更新过,而pushdown时一定要保证是子孙真正需要的值
还有就是数据量较大时一定要用scanf
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAX 100100
using namespace std;
int n,m,sum[MAX<<2],add[MAX<<2];
void pushdown(int root){
if(root*2>=MAX*4){
add[root]=0;
return ;
}
add[root<<1]=add[root];
add[root<<1|1]=add[root];
add[root]=0;
}
void pushup(int root,int all){
if(add[root<<1]){
sum[root<<1]=add[root<<1]*(all-all/2);
pushdown(root<<1);
}
if(add[root<<1|1]){
sum[root<<1|1]=add[root<<1|1]*(all/2);
pushdown(root<<1|1);
}
// cout<<"up"<<root<<" "<<(all-all/2)<<" "<<sum[root<<1]<<" "<<sum[root<<1|1]<<endl;
sum[root]=sum[root<<1]+sum[root<<1|1];
}
void build(int root,int l,int r){
add[root]=0;
if(l==r){
sum[root]=1;
return;
}
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
pushup(root,r-l+1);
}
void update(int root,int Left,int Right,int l,int r,int v){
if(Right<l||Left>r)
return;
if(Right<=r&&Left>=l){
add[root]=v;
sum[root]=v*(Right-Left+1);
pushdown(root);
return;
}
if(add[root])
pushdown(root);
int mid=(Right+Left)>>1;
update(root<<1,Left,mid,l,r,v);
update(root<<1|1,mid+1,Right,l,r,v);
pushup(root,Right-Left+1);
}
int main(){
int T,l,r,v,cases=1;
cin>>T;
while(T--){
memset(add,0,sizeof(add));
scanf("%d %d",&n,&m);
build(1,1,n);
while(m--){
scanf("%d%d%d",&l,&r,&v);
update(1,1,n,l,r,v);
}
printf("Case %d: The total value of the hook is %d.\n",cases++,sum[1]);
}
return 0;
}