1. 程式人生 > 實用技巧 >3468 A Simple Problem with Integers

3468 A Simple Problem with Integers

資源限制

Time Limit: 5000MS  Memory Limit: 131072K  Case Time Limit: 2000MS

Description

You have N integers, A1, A2, ... , 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 A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa

, Aa+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. 這是一道樹狀陣列-[區間更新 區間查詢]模板題,詳情點選這裡.

以下,A[i]代表原陣列,D[j]代表差分陣列.

ni = 1A[i] =∑ni = 1ij = 1D[j];

則 A[1]+A[2]+...+A[n]

= (D[1]) + (D[1]+D[2]) + ... + (D[1]+D[2]+...+D[n])

= n*D[1] + (n-1)*D[2] +... +D[n]

= n * (D[1]+D[2]+...+D[n]) - (0*D[1]+1*D[2]+...+(n-1)*D[n])

所以上式可以變為∑ni = 1A[i] = n*∑ni = 1D[i] - ∑ni = 1( D[i]*(i-1) );

於是,維護兩個樹狀陣列,sum1[i] = D[i],sum2[i] = D[i]*(i-1);

※注意:題目中也有提醒道,本題資料較大,要用long long.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <string>
 6 #include <cmath>
 7 #include <algorithm>
 8 #define INF 0x3f3f3f3f
 9 #define zero 1e-7
10 
11 using namespace std;
12 typedef long long ll;
13 const ll mod=1000000007;
14 const ll max_n=100005;
15 ll a[max_n]={0};
16 ll sum1[max_n]={0}, sum2[max_n]={0};
17 ll n;
18 
19 ll lowbit(ll x) {
20     return x&(-x);
21 }
22 
23 void update(ll i, ll k) {
24     ll temp=i;
25     while(i<=n) {
26         sum1[i]+=k;
27         sum2[i]+=(temp-1)*k;
28         i+=lowbit(i);
29     }
30 }
31 
32 ll getsum(ll i) {
33     ll res=0;
34     ll temp=i;
35     while(i>0) {
36         res+=temp*sum1[i]-sum2[i];
37         i-=lowbit(i);
38     }
39     return res;
40 }
41 
42 int main() {
43     ll q;
44     cin>>n>>q;
45     for(ll i=1; i<=n; i++) {
46         scanf("%I64d", &a[i]);
47         update(i, a[i]-a[i-1]);
48     }
49     char opt;
50     ll a, b, c;
51     for(ll i=0; i<q; i++) {
52         scanf(" %c", &opt);
53         if(opt=='C') {
54             scanf("%I64d %I64d %I64d", &a, &b, &c);
55             update(a, c);
56             update(b+1, -c);
57         }
58         else {
59             scanf("%I64d %I64d", &a, &b);
60             printf("%I64d\n", getsum(b)-getsum(a-1));
61         }
62     }
63     return 0;
64 }