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
思路
线段树区间更新 + 区间求和,其实就是一个lazy模板,值得注意的是题目坑点比较多,用long long存储数据比较保险,还有就是最好利用scanf读入,否则容易超时。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define ll long long
#define lson k<<1,l,m
#define rson k<<1|1,m+1,r
using namespace std;
const int maxn = 1e5+50;
ll a[maxn],s[maxn<<2],lazy[maxn<<2];
void build(int k,int l,int r)
{
if(l == r){
s[k] = a[l];
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
s[k] = s[k<<1] + s[k<<1|1];
}
void push_down(int k,int m)
{
if(lazy[k]){
lazy[k<<1] += lazy[k];
lazy[k<<1|1] += lazy[k];
s[k<<1] += ((ll)(m-(m>>1))*lazy[k]);
s[k<<1|1] += ((ll)((m>>1)*lazy[k]));
lazy[k] = 0;
}
}
void update(int k,int l,int r,int ql,int qr,int ans)
{
if(qr < l || r < ql){
return ;
}
if(ql <= l && r <= qr){
lazy[k] += ans;
s[k] += ((ll)(r-l+1)*ans);
return ;
}
push_down(k,r-l+1);
int m = (l+r)>>1;
update(lson,ql,qr,ans);
update(rson,ql,qr,ans);
s[k] = s[k<<1] + s[k<<1|1];
}
ll query(int k,int l,int r,int ql,int qr)
{
if(qr < l || r < ql){
return 0;
}
if(ql <= l && r <= qr){
return s[k];
}
push_down(k,r-l+1);
int m = (l+r)>>1;
ll s1 = query(lson,ql,qr);
ll s2 = query(rson,ql,qr);
return s1+s2;
}
int main()
{
int t,n,m;
while(~scanf("%d%d",&n,&m)){
memset(lazy,0,sizeof(lazy));
memset(s,0,sizeof(s));
for(int i = 1;i <= n;i++){
scanf("%lld",&a[i]);
}
build(1,1,n);
while(m--){
char str[5];
int x,y,z;
scanf("%s",str);
if(str[0] == 'Q'){
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,1,n,x,y));
}
else{
scanf("%d%d%d",&x,&y,&z);
update(1,1,n,x,y,z);
}
}
}
return 0;
}
愿你走出半生,归来仍是少年~