- 区间加,区间求和(cdq分治)
1
- @ 2026-8-4 9:40:28
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
void solve() {
int n, m;
cin >> n >> m;
vector<array<int, 5>> a;
auto addChange1 = [&] (int r, int v) {
if (r < 1) return;
a.push_back({r, 0, v, 0, 0});
};
auto addChange = [&] (int l, int r, int v) {
addChange1(l - 1, -v);
addChange1(r, v);
};
for (int i = 1; i <= n; i++) {
int x; cin >> x; addChange(i, i, x);
}
vector<ll> ans;
for (int i = 1, id = 0; i <= m; i++) {
int o, x, y, v;
cin >> o >> x >> y;
if (o == 1) {
cin >> v;
addChange(x, y, v);
} else {
a.push_back({y, 1, 0, id, 1});
if (x > 1) a.push_back({x - 1, 1, 0, id, -1});
id++;
ans.push_back(0);
}
}
auto cdq = [&] (auto &&self, int l, int r)->void {
if (l == r) return;
int mid = l + r >> 1;
self(self, l, mid);
self(self, mid + 1, r);
sort(a.begin() + l, a.begin() + mid + 1);
sort(a.begin() + mid + 1, a.begin() + r + 1);
// cout << "start:" << l << ' ' << r << endl;
// for (int i = l; i <= r; i++) {
// auto [r, o, v, id, f] = a[i];
// cout << r << ' ' << o << ' ' << v << ' ' << id << ' ' << f << endl;
// }
ll sum = 0;
for (int j = mid + 1, i = l; j <= r; j++) {
auto [r, o, v, id, f] = a[j];
if (o == 0) continue;
while (i <= mid && a[i][0] <= a[j][0]) {
if (a[i][1] == 0) sum += a[i][2] * 1ll * a[i][0];
i++;
}
// cout << " i = " << i << " j = " << j << " sum = " << sum << '\n';
// cout << "add: id = " << id << "sum = " << sum * f << '\n';
ans[id] += sum * f;
}
sum = 0;
for (int j = r, i = mid; j >= mid + 1; j--) {
auto [r, o, v, id, f] = a[j];
if (o == 0) continue;
while (i >= l && a[i][0] > a[j][0]) {
if (a[i][1] == 0) sum += a[i][2];
i--;
}
ans[id] += 1ll * sum * f * r;
// cout << "add: id = " << id << "sum = " << sum * f * r << '\n';
}
// cout << "end:" << l << ' ' << r << endl;
};
cdq(cdq, 0, (int)a.size() - 1);
for (auto x : ans) cout << x << '\n';
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
int t = 1;
while (t--) solve();
return 0;
}
/*
g++ -std=c++20 1.cpp -o 1 && 1 < in.txt > out.txt
*/
0 条评论
目前还没有评论...
信息
- ID
- 550
- 时间
- ms
- 内存
- MiB
- 难度
- 7
- 标签
- 递交数
- 17
- 已通过
- 9
- 上传者