分块
#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); }