HDU 1698 Just a Hook 线段树区间更新、

时间:2023-03-08 16:56:28

来谈谈自己对延迟标记(lazy标记)的理解吧、

lazy标记的主要作用是尽可能的降低时间复杂度、

这样说吧、 如果你不用lazy标记,那么你对于一个区间更新的话是要对其所有的子区间都更新一次,但如果用lazy标记的话、 就只需要更新这一个区间然后加一个标记,那么如果要访问这个区间的子区间,因为有lazy标记,所以下次访问会将区间的lazy标记传递给子区间,让后去更新子区间,这样我们不必在每次区间更新操作的时候更新该区间的全部子区间,等下次查询到这个区间的时候只需要传递lazy标记就可以了

但从时间复杂度上来讲,肯定是划算的,那么对于要访问我们开始更新区间的子区间又如何呢、 一样,我们有又需要更新的所要查找的子区间,然后加一个lazy标记,等下次更新的时候传递这个标记就好了、

另外两个push函数放的位置可谓是递归的精髓、

递归真的好神奇、

- - 初学者、  言语方面可能表达不严谨

 #include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=;
int h,w,n;
int col[maxn<<];
int sum[maxn<<];
void pushup(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
}
void pushdown(int rt,int m)
{
if(col[rt]){ //传递标记并更新区间
col[rt<<]=col[rt<<|]=col[rt];
sum[rt<<]=(m-(m>>))*col[rt];
sum[rt<<|]=(m>>)*col[rt];
col[rt]=;
}
}
void build(int l,int r,int rt)
{
col[rt]=;
sum[rt]=;
if(l==r) return;
int m=(l+r)>>;
build(l,m,rt<<);
build(m+,r,rt<<|);
pushup(rt); //递归尿性向上更新、
}
void updata(int L,int R,int c,int l,int r,int rt)
{
if(L<=l && r<=R){
col[rt]=c;
sum[rt]=c*(r-l+);
return;
}
pushdown(rt,r-l+); //传递标记、   不得不说这两个push函数放的位置真的很能体现递归的作用
int m=(l+r)>>;
if(L<=m) updata(L,R,c,l,m,rt<<);
if(R>m) updata(L,R,c,m+,r,rt<<|);
pushup(rt); //利用递归的尿性向上更新区间和、
}
int main()
{
int t,n,m;
int p=;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
build(,n,);
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
updata(a,b,c,,n,);
}
printf("Case %d: The total value of the hook is %d.\n",p++,sum[]);
}
return ;
}