分块
分块
分块是一个比较暴力的数据结构,思路简单,是\(\sqrt{N}\)型数据结构。对比树状数组和线段树效率低很多。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10, M = 350; // M = log(N)
int n,m,len;
ll add[M], sum[M];
ll w[N];
ll X;
int L,R;
char op[2];
inline int get(int i){
return i / len;
}
void modify(int l,int r,ll x){
if(get(l) == get(r)){
for(int i = l; i <= r; ++i){
w[i] += x;
sum[get(i)] += x;
}
}else{
int i = l, j = r;
while(get(i) == get(l)){
w[i] += x;
sum[get(i)] += x;
++i;
}
while(get(j) == get(r)){
w[j] += x;
sum[get(j)] += x;
--j;
}
for(int k = get(i); k <= get(j); ++k){
sum[k] += len * x;
add[k] += x;
}
}
}
ll query(int l,int r){
ll ans = 0;
if(get(l) == get(r)){
for(int i = l; i <= r; ++i){
ans += w[i] + add[get(i)];
}
}else{
int i = l, j = r;
while(get(i) == get(l)){
ans += w[i] + add[get(i)];
++i;
}
while(get(j) == get(r)){
ans += w[j] + add[get(j)];
--j;
}
for(int k = get(i); k <= get(j); ++k){
ans += sum[k];
}
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
len = sqrt(n);
for(int i = 1; i <= n; ++i){
scanf("%lld",&w[i]);
sum[get(i)] += w[i];
}
while(m--){
scanf("%s%d%d",op,&L,&R);
if(*op == 'C'){
scanf("%lld",&X);
modify(L,R,X);
}else{
printf("%lld\n",query(L,R));
}
}
return 0;
}
---- suffer now and live the rest of your life as a champion ----