区间覆盖:
题目链接:https://vjudge.net/contest/269834#problem/D
AC代码:
#include
#include
#include
#include
#include
#include
#include
区间累加:
#include
#include
#include
#include
#include
#include
#include
反思:
通过观察上面的两个样例,可以感觉到线段树只有这里不太一样。
1/--------------------------------------------------\
if(L<=l&&R>=r)
{
a[rt]+=p*(r-l+1);
col[rt]+=p;
return ;
}
void down(ll rt,ll len)
{
if(col[rt]!=0)
{
col[rt<<1]+=col[rt];
col[rt<<1|1]+=col[rt];
a[rt<<1]+=col[rt]*(len-len/2);
a[rt<<1|1]+=col[rt]*(len/2);
col[rt]=0;
}
}
/-----------------------------------------------------\
2
/----------------------------------------------------\
if(L<=l&&R>=r)
{
a[rt]=p*(r-l+1);
col[rt]=p;
return ;
}
if(col[rt]!=-1)
{
col[rt<<1]=col[rt<<1|1]=col[rt];
int mid=(l+r)>>1;
a[rt<<1]=col[rt]*(mid-l+1);
a[rt<<1|1]=col[rt]*(r-mid);
col[rt]=-1;
}
/------------------------------------------------------\
观看这两个线段树的区别,第一个是用来累加的,第二个是用来覆盖的。
对于第一个来说,每一个父节点存储的是当前这个点以及当前这个点往下的权值,而对于第二个来说,存储的是当前这个点的颜色,每一次操作并不会收到以前的影响,所以直接覆盖掉就可以了,但是第一个如果覆盖掉的话,以前的权值就会消失,这就是这两个题的不同。