POJ3468——A Simple Problem with Integers (线段树区间加值,区间求和)
- 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;
}