poj 3468 A Simple Problem with Integers(线段树——成段更新问题)

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

代码:

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 __int64 s[400010];
 5 __int64 t[400010];//延迟数组,标记
 6 void push(int w)
 7 {
 8     s[w]=s[w*2]+s[w*2+1];
 9 }
10 void pushdown(int w, int d)
11 {
12     if(t[w])//如果延迟,向下更新
13     {
14         t[w*2]+=t[w];
15         t[w*2+1]+=t[w];
16         s[w*2]+=(t[w]*(d-(d/2)));
17         s[w*2+1]+=t[w]*(d/2);
18         t[w]=0;//去除标记
19     }
20 }
21 void build(int l,int r,int w)
22 {
23     t[w]=0;
24     if(l==r)
25     {
26         scanf("%I64d",&s[w]);
27         return ;
28     }
29     int m=(l+r)/2;
30     build(l,m,w*2);
31     build(m+1,r,w*2+1);
32     push(w);
33 }
34 void add(int l,int r,int L,int R,int num,int w)
35 {
36     if(L<=l&&R>=r)  //执行一次便返回,但不一定是叶子节点
37     {
38         t[w]+=num;
39         s[w]+=num*(r-l+1);
40         return ;
41     }
42     pushdown(w,r-l+1);//更新
43     int m=(l+r)/2;
44     if(L<=m)
45     add(l,m,L,R,num,w*2);
46     if(R>m)
47     add(m+1,r,L,R,num,w*2+1);
48     push(w);
49 }
50 __int64 query(int l,int r,int L,int R,int w)
51 {
52     if(L<=l&&R>=r)
53     {
54         return s[w];
55     }
56     pushdown(w,r-l+1);//更新
57     int m=(l+r)/2;
58     __int64 res=0;
59     if(L<=m)
60     res+=query(l,m,L,R,w*2);
61     if(R>m)
62     res+=query(m+1,r,L,R,w*2+1);
63     return res;
64 }
65 int main()
66 {
67     int m,n,i,a,b,c;
68     char str;
69     scanf("%d%d",&n,&m);
70     build(1,n,1);
71 
72     for(i=1;i<=m;i++)
73     {
74         scanf("%*c%c",&str);
75         if(str=='Q')
76         {
77             scanf("%d%d",&a,&b);
78             printf("%I64d\n",query(1,n,a,b,1));
79         }
80         else
81         {
82             scanf("%d%d%d",&a,&b,&c);
83             add(1,n,a,b,c,1);
84         }
85     }
86     return 0;
87 }
原文地址:https://www.cnblogs.com/wanglin2011/p/2637112.html