POJ 3468 A Simple Problem with Integers(线段树)

A Simple Problem with Integers
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 126311   Accepted: 39238
Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.

Source

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 typedef long long ll;
 6 using namespace std;
 7 int n, q;
 8 struct node
 9 {
10     int l, r;
11     ll date;//区间内每个数都要加的数
12     ll datb;//数据的和
13 }a[400005];
14 
15 
16 void build(int l,int r,int k)
17 {
18     a[k].l = l; a[k].r = r;
19     if (r == l)
20     {
21         scanf("%lld", &a[k].datb);
22         return;
23     }
24     int mid = (l + r) / 2;//传的是l和r,不是a[k].l和a[k].r
25     build(l, mid , 2 * k);
26     build(mid + 1, r, 2 * k + 1);
27     a[k].datb = a[2 * k].datb + a[2 * k + 1].datb;
28 }
29 
30 void add(int k,int l,int r,int v)
31 {
32     if (a[k].l >= l && r >= a[k].r)//如果区间刚好在a[k].l和a[k].r之间
33         a[k].date += v;//每个数都要加,所以放到date中
34     else if(a[k].l<=r&&l<=a[k].r)//部分重叠的话
35     {
36         a[k].datb+= (min(r, a[k].r) - max(l, a[k].l)+1)*v;//我加号居然忘了
37         add(2 * k, l,r, v);
38         add(2 * k + 1,l, r, v);
39     }
40     //否则跳出循环
41 }
42 
43 ll Sum(int l, int r,int k)
44 {
45     if (l > a[k].r||r < a[k].l)
46         return 0;
47     else if (l <= a[k].l&&r >= a[k].r)
48     {
49         /*cout << "a[k].l " << a[k].l << " a[k].r " << a[k].r << endl;
50         cout << a[k].datb + a[k].date *(a[k].r - a[k].l + 1) << endl;*/
51         return a[k].datb + a[k].date *(a[k].r - a[k].l + 1);
52     }
53     else
54     {
55         ll ans = (min(a[k].r, r) - max(a[k].l, l)+1)*a[k].date;
56         ans += Sum(l, r, k * 2);//传的是l和r,不是a[k].l和a[k].r
57         ans += Sum(l, r, k * 2 + 1);
58         return ans;
59     }
60 }
61 
62 int main()
63 {
64     while (~scanf("%d%d", &n, &q))
65     {
66         for (int i = 0; i <= 400000; i++)
67             a[i].datb = a[i].date = 0;
68         build(1, n, 1);
69         while (q--)
70         {
71             char s;
72             int x, y;
73             cin >> s >> x >> y;
74             if (s == 'C')
75             {
76                 int z;
77                 cin >> z;
78                 add(1, x, y, z);
79             }
80             else
81             {
82                 ll sum = Sum(x, y, 1);
83                 printf("%lld\n", sum);
84             }
85         }
86     }
87     return 0;
88 }

 

 
posted on 2018-03-02 20:49  蔡军帅  阅读(86)  评论(0编辑  收藏  举报