poj3468A Simple Problem with Integers(成段操作)

http://acm.sdut.edu.cn/bbs/read.php?tid=5651

。。本来只会向上更新 现在学习了如何向下更新 延迟标记法。。。使复杂度降低

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<string.h>
 4 using namespace std;
 5 #define max 100000
 6 __int64 s[max*4],te[max*4];
 7 void pushup(int w)
 8 {
 9     s[w] = s[2*w]+s[2*w+1];
10 }
11 void pushdown(int w,int m)
12 {
13     if(te[w])
14     {
15         te[2*w]+=te[w];
16         te[2*w+1] += te[w];
17         s[2*w] += (te[w]*(m-(m/2)));
18         s[2*w+1]+=(te[w]*(m/2));
19         te[w] = 0;//将延迟标记去除
20     }
21 }
22 void build(int l,int r,int w)
23 {
24     te[w] = 0;
25     if(l==r)
26     {
27         scanf("%I64d",&s[w]);
28         return ;
29     }
30     int m = (l+r)/2;
31     build(l,m,2*w);
32     build(m+1,r,2*w+1);
33     pushup(w);
34 }
35 void add(int a,int b,int da,int l,int r,int w)
36 {
37     if(a<=l&&b>=r)
38     {
39         te[w] += da;//多次延迟标记
40         s[w]+=da*(r-l+1);
41         return ;
42     }
43     pushdown(w,r-l+1);//更新
44     int m = (l+r)/2;
45     if(a<=m)
46     add(a,b,da,l,m,2*w);
47     if(b>m)
48     add(a,b,da,m+1,r,2*w+1);
49     pushup(w);
50 }
51 __int64 search(int a,int b,int l,int r,int w)
52 {
53     if(a<=l&&b>=r)
54     {
55         return s[w];
56     }
57     pushdown(w,r-l+1);
58     int m=(l+r)/2;
59     __int64 re = 0;
60     if(a<=m)
61     re+=search(a,b,l,m,2*w);
62     if(b>m)
63     re+=search(a,b,m+1,r,2*w+1);
64     return re;
65 }
66 int main()
67 {
68     int i,j,k,n,m,t,a,b,c;
69     char z;
70     scanf("%d%d",&n,&m);
71     build(1,n,1);
72     while(m--)
73     {
74         scanf("%*c%c",&z);
75         if(z=='Q')
76         {
77             scanf("%d%d",&a,&b);
78             printf("%I64d\n",search(a,b,1,n,1));
79         }
80         else
81         {
82             scanf("%d%d%d",&a,&b,&c);
83             add(a,b,c,1,n,1);
84         }
85     }
86     return 0;
87 }
原文地址:https://www.cnblogs.com/shangyu/p/2631053.html