题意:给t个例子,n个值,m个寻问,每次对区间(l,r)进行修改 ,只能将其修改为1,2,3中的一种
思路:对于线段树 区间直接修改 与 区间每项相加 之间是有一些差别的,要理解透 push_down与lazy tag的意义
完整代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int t=0,n=0; int seg[400010],tag[400010]; int m=0,x=0,y=0,k=0;//k为修改的值 void build(int pos,int l,int r){ if(l==r){ seg[pos]=1; tag[pos]=0; return; } else{ int mid=(l+r)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); seg[pos]=seg[pos<<1]+seg[pos<<1|1]; } } void down(int pos,int num){ if(tag[pos]){ seg[pos<<1]=tag[pos]*(num-num/2); seg[pos<<1|1]=tag[pos]*(num/2);//attention! tag[pos<<1]=tag[pos<<1|1]=tag[pos]; tag[pos]=0; } } void update(int pos,int l,int r){ if(x>r||y<l) return; if(x<=l&&y>=r){ seg[pos]=k*(r-l+1); tag[pos]=k; return; } down(pos,r-l+1); int mid=(l+r)/2; update(pos<<1,l,mid); update(pos<<1|1,mid+1,r); seg[pos]=seg[pos<<1]+seg[pos<<1|1]; } int main(){ scanf("%d",&t); for(int i=1;i<=t;i++){ memset(seg,0,sizeof(seg)); memset(tag,0,sizeof(tag)); scanf("%d",&n); build(1,1,n); scanf("%d",&m); for(int j=1;j<=m;j++){ scanf("%d%d%d",&x,&y,&k); update(1,1,n); } printf("Case %d: The total value of the hook is %d. ",i,seg[1]); } return 0; }