A Simple Problem with Integers
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions:40260 | Accepted: 11693 | |
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.
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define lson l, m, rt<<1 5 #define rson m+1, r, rt<<1|1 6 #define LL long long int 7 const int maxn = 111111; 8 LL col[maxn<<2], sum[maxn<<2]; 9 void PushUP(int rt){ 10 sum[rt] = sum[rt<<1] + sum[rt<<1|1]; 11 } 12 void PushDown(int rt, int m){ 13 if (col[rt]){ 14 col[rt<<1] += col[rt]; col[rt<<1|1] += col[rt]; 15 sum[rt<<1] += (LL)(col[rt] *(m-(m>>1))); 16 sum[rt<<1|1] += (LL)(col[rt] *(m>>1)); 17 col[rt] = 0; 18 } 19 } 20 void build(int l, int r, int rt){ 21 col[rt] = 0; if (l == r) {scanf("%lld", sum + rt); return;} 22 int m = (l + r) >> 1; build(lson); build(rson); PushUP(rt); 23 } 24 void update(int L, int R, int c, int l, int r, int rt){ 25 if (L <= l && R >= r) {col[rt] += c; sum[rt] += (LL)(c*(r-l+1)); return;} 26 PushDown(rt, r - l + 1); 27 int m= (l + r) >> 1; 28 if (L <= m) update(L, R, c, lson); if (R > m) update(L, R, c, rson); 29 PushUP(rt); 30 } 31 LL query(int L, int R, int l, int r, int rt){ 32 if (L <= l && R >= r){return sum[rt];} 33 PushDown(rt, r - l + 1); int m = (l + r) >> 1; LL ret = 0; 34 if (L <= m) ret += query(L, R, lson); if (R > m) ret += query(L, R, rson); 35 PushUP(rt); 36 return ret; 37 } 38 int main(void){ 39 int n, q; 40 #ifndef ONLINE_JUDGE 41 freopen("poj3468.in", "r", stdin); 42 #endif 43 while (~scanf("%d%d", &n, &q)){ 44 build(1, n, 1); 45 while (q--){ 46 char a[2]; scanf("%s", a); int m, b, c; 47 if (a[0] == 'Q') 48 {scanf("%d%d", &m, &b);printf("%lld\n",query(m, b, 1, n, 1));} 49 else { 50 scanf("%d%d%d", &m, &b, &c); update(m, b, c, 1, n, 1); 51 } 52 } 53 } 54 return 0; 55 }
更新区间的线段树。敲了好几遍,差不多熟悉了,其实敲多了也就明白了。