A Simple Problem with Integers
| Time Limit: 5000MS |
|
Memory Limit: 131072K |
| Total Submissions: 47740 |
|
Accepted: 14052 |
| 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 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4
Sample Output
455915
Hint
The sums may exceed the range of 32-bit integers.
Code:
C命令的話就添加
Q命令的話就查詢
結構體體就一個數表示這一段區間的和,另一個表示後來加上的數
查詢的時候再往下加往下更新, 節約時間
添加的時候找到完全相同區間的時候只用更新add,但是它的父親結點值也要更新,
#include<stdio.h>#include<string.h>#define M 100005typedef struct node{int lside,rside;__int64 val,add;} node;node tree[M*4];int a[M];void tree_build(int num,int l,int r){int mid,next;tree[num].lside = l;tree[num].rside = r;tree[num].add = 0;if(l==r){tree[num].val = a[l];return;}mid = (l+r)>>1;next = num<<1;//printf("next:%d mid:%d\n",next,mid);tree_build(next,l,mid);tree_build(next+1,mid+1,r);tree[num].val = tree[next].val + tree[next+1].val;}void add(int num,int l,int r,int val){if(tree[num].lside==l && tree[num].rside==r){tree[num].add += val;return;}tree[num].val += (r-l+1)*val;//這裡要更新int mid,next;mid = (tree[num].lside+tree[num].rside)>>1;next = num<<1;if(r<=mid) add(next,l,r,val);else if(l>mid) add(next+1,l,r,val);else{add(next,l,mid,val);add(next+1,mid+1,r,val);}}__int64 query(int num,int l,int r){int next,mid;next = num<<1;mid = (tree[num].lside+tree[num].rside)>>1;if(tree[num].lside==l && tree[num].rside==r){return (tree[num].val + tree[num].add*(tree[num].rside - tree[num].lside + 1));}else{tree[next].add += tree[num].add;//add往下傳遞tree[next+1].add += tree[num].add;tree[num].val += tree[num].add*(tree[num].rside - tree[num].lside + 1);tree[num].add = 0;//傳遞過後自己變成0}if(r<=mid) return query(next,l,r);else if(l>mid) return query(next+1,l,r);else return query(next,l,mid) + query(next+1,mid+1,r);}int main(){int n,q,i,v,l,r;while(scanf("%d%d",&n,&q)!=EOF){for(i=1;i<=n;i++)scanf("%d",&a[i]);tree_build(1,1,n);char ch[2];//這裡單一字元的話後面要加getchar()while(q--){scanf("%s",ch);if(ch[0] == 'Q'){scanf("%d%d",&l,&r);printf("%I64d\n",query(1,l,r));}if(ch[0] == 'C'){scanf("%d%d%d",&l,&r,&v);add(1,l,r,v);}}}return 0;}