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
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 = 1 ∑ij = 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 }