分块

#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define INF 0x3f3f3f3f
#define MAXN 300010
#define MAXM 3010
#define _ 0

inline int read() {
    int  x = 0,ff = 1, ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') ff = -1;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * ff;
}

inline void write(int x) {
    if(x < 0) putchar('-'),x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int n,m,t,L[MAXN],R[MAXN],a[MAXN],id[MAXN],sum[MAXN],add[MAXN];


void change(int l,int r,int d) {
    int p = id[l],q = id[r];
    if(p == q) {
        for(int i = l; i <= r; ++i) a[i] += d;
        sum[p] += d * (r - l + 1);
    }
    else {
        for(int i = p + 1; i <= q - 1; ++i) add[i] += d;
        for(int i = l; i <= R[p]; ++i) a[i] += d;
        sum[p] += d * (R[p] - l + 1);
        for(int i = L[q]; i <= r; ++i) a[i] += d;
        sum[q] += d * (r - L[q] + 1);
    }
}

int ask(int l, int r) {
    int ans = 0;
    int p = id[l],q = id[r];
    if(p == q) {
        for(int i = l; i <= r; ++i) ans += a[i];
        ans += add[p] * (r - l + 1);
    }
    else {
        for(int i = p + 1; i <= q - 1; ++i)
            ans += sum[i] + add[i] * (R[i] - L[i] + 1);
        for(int i = l; i <= R[p]; ++i) ans += a[i];
        ans += add[p] * (R[p] - l + 1);
        for(int i = L[q]; i <= r; ++i) ans += a[i];
        ans += add[q] * (r - L[q] + 1);
    }
    return ans;
}

int main() {
    n = read(); m = read();
    for(int i = 1; i <= n; ++i ) 
        a[i] = read();
    t = sqrt(n);
    for(int i = 1; i <= t; ++i) {
        L[i] = (i - 1) * t + 1;
        R[i] = i * t;
    }
    if(R[t] < n) ++t,L[t] = R[t - 1] + 1,R[t] = n;
    for(int i = 1; i <= t; ++i) {
        for(int j = L[i]; j <= R[i]; ++j) {
            id[j] = i;
            sum[i] += a[j];
        }
    }
    while(m--) {
        int op,x,y;
        op = read(); x = read(); y = read();
        if(op == 1) {
            int d;
            d = read();
            change(x,y,d);
        }
        else write(ask(x,y)),putchar('\n');
    }
    return (0^_^0);
}
                                                                               

 

posted @ 2019-03-26 13:48  海边微风起  阅读(167)  评论(0编辑  收藏  举报