ll a[N], sum[N], add[N]; //原数组,区间和,增量标记 int L[N], R[N]; //每段左右端点 int pos[N]; //每个位置属于哪一段 int n, m, t;
voidchange(int l, int r, ll d) { int p = pos[l], q = pos[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); } }
ll ask(int l, int r) { int p = pos[l], q = pos[r]; ll ans = 0; 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; }
voiddeer() { cin >> n >> m; for (int i = 1;i <= n;i++) cin >> a[i]; //分块 t = sqrt(n); for (int i = 1;i <= t;i++) { L[i] = (i - 1) * sqrt(n) + 1; R[i] = i * sqrt(n); } 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++) { pos[j] = i; sum[i] += a[j]; } } //指令 while (m--) { char op[3]; int l, r, d; cin >> op >> l >> r; if (op[0] == 'C') //加d { cin >> d; change(l, r, d); } else cout << ask(l, r) << "\n"; //求和 }