Poj 3468--线段树

http://poj.org/problem?id=3468

线段树成段更新模版题。。但是这里这个惰性标记有点神奇,,看了好久才理解。。

这里简单的讲下懒惰标记,懒惰标记即是要修改一个区间的时候,暂时不需要修改区间中的每个点,加一个标志代表这个区间被修改了,等到需要查询一个小区间的时候再具体修改。至于为什么要这样呢,不妨这么考虑,当更新一段区间的时候,如果没有懒惰标记,一开始如果找到的区间比要更新的区间大,那么这个大的区间里的每个点都需要修改,这样时间复杂度就是o(n)了,这跟没用线段树一样,至于单点更新为什么不需要这个呢,是因为单点更新都是更新一个点,所以不会出现更新区间这样的问题,而采用了懒惰标记,只是对当前父亲节点进行标记,当找到更新的区间时,才会进行更新,而不是在每次找区间的时候都更新,这样的时间复杂度才是线段树的复杂度。

代码:

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define maxn 100100
 5 #define lson l,m,rt<<1
 6 #define rson m+1,r,rt<<1|1
 7 long long sum[maxn<<2],flag[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 num)
13 {
14     flag[rt<<1]+=flag[rt];
15     flag[rt<<1|1]+=flag[rt];
16     sum[rt<<1]+=(num-(num>>1))*flag[rt];
17     sum[rt<<1|1]+=(num>>1)*flag[rt];
18     flag[rt]=0;
19 }
20 void build(int l,int r,int rt)
21 {
22     flag[rt]=0;
23     if(l==r)
24     {
25         scanf("%lld",&sum[rt]);
26         return ;
27     }
28     int m=(l+r)>>1;
29     build(lson);
30     build(rson);
31     Pushup(rt);
32 }
33 void update(int L,int R,int w,int l,int r,int rt)
34 {
35     if(L<=l&&r<=R)
36     {
37         flag[rt]+=w;
38         sum[rt]+=(long long)(r-l+1)*w;
39         return;
40     }
41     Pushdown(rt,r-l+1);
42     int m=(l+r)>>1;
43     if(L<=m) update(L,R,w,lson);
44     if(R>m) update(L,R,w,rson);
45     Pushup(rt);
46 }
47 long long query(int L,int R,int l,int r,int rt)
48 {
49     if(L<=l&&r<=R)
50         return sum[rt];
51     Pushdown(rt,r-l+1);
52     long long ret=0;
53     int m=(l+r)>>1;
54     if(L<=m) ret+=query(L,R,lson);
55     if(R>m) ret+=query(L,R,rson);
56     return ret;
57 }
58 int main()
59 {
60     int n,m,a,b,w;
61     char c[2];
62     while(~scanf("%d %d",&n,&m))
63     {
64         build(1,n,1);
65         while(m--)
66         {
67             scanf("%s",&c);
68             if(c[0]=='Q')
69             {
70                 scanf("%d %d",&a,&b);
71                 printf("%lld\n",query(a,b,1,n,1));
72             }
73             else
74             {
75                 scanf("%d %d %d",&a,&b,&w);
76                 update(a,b,w,1,n,1);
77             }
78         }
79     }
80     return 0;
81 }

 

posted on 2013-02-07 21:41  acoderworld  阅读(124)  评论(0)    收藏  举报

导航