给定一个长度为 N 的数列 a,以及 M条指令,每条指令可能是以下两种之一:
C l r d
,表示把 A[l],A[l+1],…,A[r] 都加上 。Q l r
,表示询问数列中第 l∼r个数的和。对于每个询问,输出一个整数表示答案。
输入格式
第一行两个整数 N,M。
第二行 N 个整数 A[i]]。
接下来 M 行表示 M条指令,每条指令的格式如题目描述所示。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
数据范围
1≤N,M≤105
|d|≤10000|
|A[i]|≤109|输入样例:
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
输出样例:
4 55 9 15
本质就是暴力,将一个数分成若干块,以块为单位进行计算
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
constexpr int N=1e5+7,M=350;
int n,m,len,a[N],sum[M],add[M];
char op[2];
int gets(int i){
return i/len;
}
void change(int l,int r,int w){
if(gets(l)== gets(r)) {
for (int i = l; i <= r; i++) {
a[i] += w, sum[gets(i)] += w;
}
}
else{
int i=l,j=r;
while(gets(i)== gets(l)) a[i]+=w,sum[gets(i)]+=w,i++;
while(gets(j)== gets(r)) a[j]+=w,sum[gets(j)]+=w,j--;
for(int k= gets(i);k<= gets(j);k++) sum[k]+=len*w,add[k]+=w;
}
}
ll sc(int l,int r){
ll res=0;
if(gets(l)== gets(r)){
for(int i=l;i<=r;i++){
res+=a[i]+add[gets(i)];
}
}
else{
int i=l,j=r;
while(gets(i)== gets(l)) res+=a[i]+add[gets(i)],i++;
while(gets(j)== gets(r)) res+=a[j]+add[gets(j)],j--;
for(int k= gets(i);k<= gets(j);k++) res+=sum[k];
}
return res;
}
int main(){
scanf("%d%d",&n,&m);
len= sqrt(n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum[gets(i)]+=a[i];
}
while(m--){
int l,r;
scanf("%s%d%d",op,&l,&r);
if(*op=='C'){
int w;
scanf("%d",&w);
change(l,r,w);
}
else{
printf("%lld\n",sc(l,r));
}
}
}