- Time limit
- 5000 ms
- Case time limit
- 2000 ms
- Memory limit
- 131072 kB
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.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.
代码:
#include <cstdio> #include <cstring> using namespace std; const int MAXN = 100005; long long Tree[MAXN*4]; int Data[MAXN]; long long add[MAXN*4]; void Build(int temp,int left,int right){ if(left == right){ Tree[temp] = Data[left]; return ; } int mid = left + (right-left)/2; Build(temp<<1,left,mid); Build(temp<<1|1,mid+1,right); Tree[temp] = Tree[temp<<1]+Tree[temp<<1|1]; } void PushDown(int temp,int left,int right){ if(add[temp]){ add[temp<<1] += add[temp]; add[temp<<1|1] += add[temp]; int mid = left + (right-left)/2; Tree[temp<<1] += (mid-left+1)*add[temp]; Tree[temp<<1|1] += (right-mid)*add[temp]; add[temp] = 0; } } void Updata(int temp,int left,int right,int ql,int qr,int value){ if(ql<=left && qr>=right){ add[temp] += value; Tree[temp] += value*(right-left+1); return; } PushDown(temp,left,right); int mid = left + (right-left)/2; if(ql<=mid)Updata(temp<<1,left,mid,ql,qr,value); if(qr>mid)Updata(temp<<1|1,mid+1,right,ql,qr,value); Tree[temp] = Tree[temp<<1]+Tree[temp<<1|1]; } long long query(int temp,int left,int right,int ql,int qr){ if(ql>right || qr<left)return 0; if(ql<=left && qr>=right)return Tree[temp]; PushDown(temp,left,right); int mid = left + (right-left)/2; long long ans = 0; if(ql<=mid)ans += query(temp<<1,left,mid,ql,qr); if(qr>mid)ans += query(temp<<1|1,mid+1,right,ql,qr); return ans; } int main(){ int N,M; char ch[3]; scanf("%d %d",&N,&M); for(int i=1 ; i<=N ; i++){ scanf("%d",&Data[i]); } Build(1,1,N); int A,B,C; while(M--){ scanf("%s",ch); if(ch[0] == 'Q'){ scanf("%d %d",&A,&B); printf("%lld\n",query(1,1,N,A,B)); } else if(ch[0] == 'C'){ scanf("%d %d %d",&A,&B,&C); Updata(1,1,N,A,B,C); } } return 0; }