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

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

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

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

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

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

递归真的好神奇、

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

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=111111;
 5 int h,w,n;
 6 int col[maxn<<2];
 7 int sum[maxn<<2];
 8 void pushup(int rt)
 9 {
10     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
11 }
12 void pushdown(int rt,int m)
13 {
14     if(col[rt]){            //传递标记并更新区间 
15         col[rt<<1]=col[rt<<1|1]=col[rt];
16         sum[rt<<1]=(m-(m>>1))*col[rt];
17         sum[rt<<1|1]=(m>>1)*col[rt];
18         col[rt]=0;
19     }
20 }
21 void build(int l,int r,int rt)
22 {
23     col[rt]=0;
24     sum[rt]=1;
25     if(l==r)    return;
26     int m=(l+r)>>1;
27     build(l,m,rt<<1);
28     build(m+1,r,rt<<1|1);
29     pushup(rt);            //递归尿性向上更新、 
30 }
31 void updata(int L,int R,int c,int l,int r,int rt)
32 {
33     if(L<=l && r<=R){
34         col[rt]=c;
35         sum[rt]=c*(r-l+1);
36         return;
37     }
38     pushdown(rt,r-l+1);        //传递标记、   不得不说这两个push函数放的位置真的很能体现递归的作用
39     int m=(l+r)>>1;
40     if(L<=m)    updata(L,R,c,l,m,rt<<1);
41     if(R>m)        updata(L,R,c,m+1,r,rt<<1|1);
42     pushup(rt);                //利用递归的尿性向上更新区间和、 
43 }
44 int main()
45 {
46     int t,n,m;
47     int p=1;
48     scanf("%d",&t);
49     while(t--){
50         scanf("%d%d",&n,&m);
51         build(1,n,1);
52         while(m--){
53             int a,b,c;
54             scanf("%d%d%d",&a,&b,&c);
55             updata(a,b,c,1,n,1);
56         }
57         printf("Case %d: The total value of the hook is %d.\n",p++,sum[1]);
58     }
59     return 0;
60 }

 

posted @ 2016-03-29 22:40  我不萌、我要高冷  阅读(185)  评论(0编辑  收藏  举报