题目链接
https://vjudge.net/problem/POJ-3468
题目
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.
题解
可以用线段树也可用树状数组。板子题。
注意数据范围,可能爆int。
代码
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll bit[maxn],bit2[maxn];
int num[maxn];
int n;
void add(ll* a,int x,ll y){
while(x<=n){
a[x]+=y;
x+=x&-x;
}
}
ll sum(ll *a,int x){
ll ans=0;
while(x){
ans+=a[x];
x-=x&-x;
}
return ans;
}
ll query(int x){
return 1LL*x*sum(bit,x)-sum(bit2,x);
}
ll query2(int l,int r){
return query(r)-query(l-1);
}
int main(){
int m;
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%d",num+i);
add(bit,i,num[i]-num[i-1]);
add(bit2,i,1LL*(i-1)*(num[i]-num[i-1]));
}
while(m--){
char c[2];
scanf("%s",c);
if(c[0]=='Q'){
int x,y;
scanf("%d%d",&x,&y);
printf("%lld\n",query2(x,y));
}else{
int x,y,d;
scanf("%d%d%d",&x,&y,&d);
add(bit,x,d);
add(bit,y+1,-d);
add(bit2,x,(x-1)*d);
add(bit2,y+1,-y*d);
}
}
return 0;
}