分块

分块

分块是一个比较暴力的数据结构,思路简单,是\(\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;
}

posted @ 2021-02-17 20:33  popozyl  阅读(81)  评论(0编辑  收藏  举报