具体细节在代码里面,算是一个区间修改,点查询吧。
成段更新(通常这对初学者来说是一道坎),
需要用到延迟标记(或者说懒惰标记),
简单来说就是每次更新的时候不要更新到底,
用延迟标记使得更新延迟到下次需要更新or询问到的时候
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
const int maxn=100005;
int n;
int sum[maxn<<3];
int col[maxn<<3];
void Pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void Pushdown(int rt,int m)
{
if(col[rt])
{
col[rt<<1]=col[rt<<1|1]=col[rt];
sum[rt<<1]=(m-(m>>1))*col[rt];
sum[rt<<1|1]=(m>>1)*col[rt];
col[rt]=0;//大注意2. 一定得记得改回来。
}
}
void build(int rt,int l,int r)
{
sum[rt]=1;
if(l==r) return;
int m=(l+r)>>1;
build(lson);
build(rson);
Pushup(rt);
}
void update(int ql,int qr,int ch,int rt,int l,int r)
{
if(ql<=l&&qr>=r)
{
col[rt]=ch;
sum[rt]=ch*(r-l+1);
return;
}
Pushdown(rt,r-l+1);//会执行这一步的前提是要修改的已经插入已经标记未传给子结点的
int m=(l+r)>>1;
if(ql<=m)
update(ql,qr,ch,lson);
if(qr>m)
update(ql,qr,ch,rson);
Pushup(rt);
}
int main()
{
int case_num,qnum,a,b,c;
scanf("%d",&case_num);
for(int i=1;i<=case_num;i++)
{
//注意1.每次还真得memset,或在build里面加入 col[i]=0;
memset(col,0,sizeof(col));
scanf("%d",&n);
build(1,1,n);
//printf("%d\n",sum[1]);
scanf("%d",&qnum);
while(qnum--)
{
scanf("%d%d%d",&a,&b,&c);
update(a,b,c,1,1,n);
//printf("~%d %d %d %d\n",sum[1],col[1],col[2],col[3]);
}
printf("Case %d: The total value of the hook is %d.\n",i,sum[1]);
}
return 0;
}