http://poj.org/problem?id=3468
成段增减,区间求和
View Code
1 #include <cstdio>
2 using namespace std;
3 const int N=100000;
4 struct segtree
5 {
6 int l,r;
7 long long s,a;
8 int m() {return (l+r)>>1;}
9 void add(long long x) {s+=x*(r-l+1); a+=x;}
10 }st[4*N];
11 void pushup(int rt)
12 {
13 st[rt].s=st[rt*2].s+st[rt*2+1].s;
14 }
15 void build(int l,int r,int rt)
16 {
17 st[rt].l=l; st[rt].r=r;
18 st[rt].a=0;
19 if (l==r)
20 {
21 scanf("%lld",&st[rt].s);
22 return;
23 }
24 int m=st[rt].m();
25 build(l,m,rt*2);
26 build(m+1,r,rt*2+1);
27 pushup(rt);
28 }
29 void pushdown(int rt)
30 {
31 if (st[rt].a==0) return;
32 st[rt*2].add(st[rt].a);
33 st[rt*2+1].add(st[rt].a);
34 st[rt].a=0;
35 }
36 void update(int a,int b,int x,int rt)
37 {
38 int l=st[rt].l,r=st[rt].r;
39 if (a<=l && r<=b)
40 {
41 st[rt].add(x);
42 return;
43 }
44 pushdown(rt);
45 int m=st[rt].m();
46 if (a<=m) update(a,b,x,rt*2);
47 if (b>m) update(a,b,x,rt*2+1);
48 pushup(rt);
49 }
50 long long query(int a,int b,int rt)
51 {
52 int l=st[rt].l,r=st[rt].r;
53 if (a<=l && r<=b) return st[rt].s;
54 pushdown(rt);
55 int m=st[rt].m();
56 long long sum=0;
57 if (a<=m) sum+=query(a,b,rt*2);
58 if (b>m) sum+=query(a,b,rt*2+1);
59 return sum;
60 }
61 int main()
62 {
63 int n,m;
64 scanf("%d%d",&n,&m);
65 build(1,n,1);
66 while (m--)
67 {
68 char op[2];
69 int a,b,c;
70 scanf("%s",op);
71 if (op[0]=='C')
72 {
73 scanf("%d%d%d",&a,&b,&c);
74 update(a,b,c,1);
75 }
76 else
77 {
78 scanf("%d%d",&a,&b);
79 long long ans=query(a,b,1);
80 printf("%lld\n",ans);
81 }
82 }
83 return 0;
84 }