結果
| 問題 |
No.876 Range Compress Query
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-09-09 10:53:19 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 257 ms / 2,000 ms |
| コード長 | 2,016 bytes |
| コンパイル時間 | 1,940 ms |
| コンパイル使用メモリ | 174,832 KB |
| 実行使用メモリ | 7,424 KB |
| 最終ジャッジ日時 | 2024-06-28 10:41:41 |
| 合計ジャッジ時間 | 5,748 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Segment {
int n;
vector<ll> node;
vector<ll> nodeG;
Segment(int N) {
n = 1;
while (n < N) n *= 2;
// 木の節点数は ceil(log2(N))^2 * 2 (葉数が2べきとなるよう調整)
node.assign(2 * n - 1, 0);
nodeG.assign(2 * n - 1, 0);
}
void add(int a, ll x, int k = 0, int l = 0,
int r = -1) { // [a,a+1)にx加算
if (r < 0) r = n;
// 含まない
if (a + 1 <= l || r <= a) return;
// 完全に含む
if (a <= l && r <= a + 1) {
node[k] += (r - l) * x;
nodeG[k] = (bool)node[k];
} else {
add(a, x, 2 * k + 1, l, (l + r) / 2);
add(a, x, 2 * k + 2, (l + r) / 2, r);
node[k] = node[2 * k + 1] + node[2 * k + 2];
nodeG[k] = nodeG[2 * k + 1] + nodeG[2 * k + 2];
}
}
ll range_sum(int a, int b, int k = 0, int l = 0,
int r = -1) { // [a,b)の要素の総和を返す
if (r < 0) r = n;
// 含まない
if (b <= l || r <= a) return 0;
// 完全に含む
if (a <= l && r <= b) return nodeG[k];
ll vl = range_sum(a, b, 2 * k + 1, l, (l + r) / 2);
ll vr = range_sum(a, b, 2 * k + 2, (l + r) / 2, r);
return vl + vr;
}
};
int main() {
int n, q;
cin >> n >> q;
Segment tree(n - 1);
ll a0, a1;
cin >> a0;
for (int i = 0; i < n - 1; i++) {
cin >> a1;
tree.add(i, a1 - a0);
a0 = a1;
}
for (int i = 0; i < q; i++) {
int task, l, r;
ll x;
cin >> task;
if (task == 1) {
cin >> l >> r >> x;
l--, r--;
if (l > 0) tree.add(l - 1, x);
if (r < n - 1) tree.add(r, -x);
} else {
cin >> l >> r;
l--, r--;
cout << tree.range_sum(l, r) + 1 << endl;
}
}
return 0;
}