- 区间加,区间求和(分块)
1
- @ 2026-8-2 10:44:38
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
const int N = 1e5 + 1;
ll a[N], st[N], ed[N], bel[N], add[N], sum[N];
int B, C;
ll query(int l, int r) {
ll res = 0;
if (bel[l] == bel[r]) {
for (int i = l; i <= r; i++) {
res += a[i] + add[bel[i]];
}
} else {
for (int i = l; i <= ed[bel[l]]; i++) {
res += a[i] + add[bel[i]];
}
for (int i = st[bel[r]]; i <= r; i++) {
res += a[i] + add[bel[i]];
}
for (int j = bel[l] + 1; j < bel[r]; j++) {
res += sum[j] + add[j] * (ed[j] - st[j] + 1);
}
}
return res;
}
void change(int l, int r, int v) {
if (bel[l] == bel[r]) {
for (int i = l; i <= r; i++) {
a[i] += v;
sum[bel[i]] += v;
}
} else {
for (int i = l; i <= ed[bel[l]]; i++) {
a[i] += v;
sum[bel[i]] += v;
}
for (int i = st[bel[r]]; i <= r; i++) {
a[i] += v;
sum[bel[i]] += v;
}
for (int j = bel[l] + 1; j < bel[r]; j++) {
add[j] += v;
}
}
}
void solve() {
int n, m;
cin >> n >> m;
assert(n <= 1e5);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
B = sqrt(n);
C = (n + B - 1) / B;
for (int j = 1; j <= C; j++) {
st[j] = (j - 1) * B + 1, ed[j] = min(n, j * B);
for (int i = st[j]; i <= ed[j]; i++) {
bel[i] = j;
sum[j] += a[i];
}
}
while (m--) {
int o, x, y, v;
cin >> o >> x >> y;
if (o == 2) {
cout << query(x, y) << '\n';
} else {
cin >> v;
change(x, y, v);
}
}
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
int t = 1;
// cin >> t;
while (t--) solve();
return 0;
}
/*
g++ -std=c++14 1.cpp -o 1 && 1 < in.txt > out.txt
g++ -std=c++17 1.cpp -o 1 && ./1 < in.txt > out.txt
*/
0 条评论
目前还没有评论...
信息
- ID
- 539
- 时间
- ms
- 内存
- MiB
- 难度
- 5
- 标签
- 递交数
- 34
- 已通过
- 15
- 上传者