結果
| 問題 | No.876 Range Compress Query |
| コンテスト | |
| ユーザー |
lowr
|
| 提出日時 | 2019-09-07 16:50:06 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 299 ms / 2,000 ms |
| コード長 | 3,533 bytes |
| 記録 | |
| コンパイル時間 | 1,965 ms |
| コンパイル使用メモリ | 202,544 KB |
| 最終ジャッジ日時 | 2025-01-07 17:11:10 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
ソースコード
#include <bits/stdc++.h>
using i64 = long long;
template <typename T, typename U = T>
class LazySegmentTree {
int size;
T tid;
T *dat;
U uid;
U *lazy;
inline T f(T a, T b) {
auto [na, la, ra] = a;
auto [nb, lb, rb] = b;
int n = na + nb + (ra >= 0 && ra == lb);
return std::make_tuple(n, la, rb);
}
inline T g(T t, U u, int len) {
auto [n, l, r] = t;
return std::make_tuple(n, l + u, r + u);
}
inline U h(U a, U b) {
return a + b;
}
void propagate(int k, int l, int r) {
if (lazy[k] == uid) return;
if (k < size - 1) {
lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
lazy[2 * k + 2] = h(lazy[2 * k + 2], lazy[k]);
}
dat[k] = g(dat[k], lazy[k], r - l);
lazy[k] = uid;
}
T update_impl(int a, int b, U x, int k, int l, int r) {
propagate(k, l, r);
if (r <= a || b <= l) return dat[k];
if (a <= l && r <= b) {
lazy[k] = h(lazy[k], x);
propagate(k, l, r);
return dat[k];
}
return dat[k] = f(update_impl(a, b, x, 2 * k + 1, l, (l + r) / 2),
update_impl(a, b, x, 2 * k + 2, (l + r) / 2, r));
}
T query_impl(int a, int b, int k, int l, int r) {
propagate(k, l, r);
if (r <= a || b <= l) return tid;
if (a <= l && r <= b) return dat[k];
return f(query_impl(a, b, 2 * k + 1, l, (l + r) / 2),
query_impl(a, b, 2 * k + 2, (l + r) / 2, r));
}
public:
LazySegmentTree(const int n, const T &tid, const U &uid) : tid(tid), uid(uid) {
size = 2;
while (size < n) size *= 2;
dat = new T[2 * size - 1];
lazy = new U[2 * size - 1];
for (int i = 0; i < 2 * size - 1; i++) {
dat[i] = tid;
lazy[i] = uid;
}
}
template <template <class> class Container>
LazySegmentTree(const Container<T> &v, const T &tid, const U &uid) : tid(tid), uid(uid) {
int n = v.size();
size = 2;
while (size < n) size *= 2;
dat = new T[2 * size - 1];
lazy = new U[2 * size - 1];
for (int i = 0; i < n; i++) dat[i + size - 1] = v[i];
for (int i = size - 1 + n; i < 2 * size - 1; i++) dat[i] = tid;
for (int i = 0; i < 2 * size - 1; i++) lazy[i] = uid;
dig(0);
}
void dig(int v) {
if (v >= size - 1) return;
dig(2 * v + 1);
dig(2 * v + 2);
dat[v] = f(dat[2 * v + 1], dat[2 * v + 2]);
}
~LazySegmentTree() {
delete[] dat;
delete[] lazy;
}
void update(const int a, const int b, const U x) {
update_impl(a, b, x, 0, 0, size);
}
T query(const int a, const int b) {
return query_impl(a, b, 0, 0, size);
}
T operator[](const int i) {
return query(i, i + 1);
}
};
int main() {
int n, q;
std::cin >> n >> q;
std::vector<std::tuple<int, i64, i64>> v;
for (int i = 0; i < n; i++) {
int a;
std::cin >> a;
v.emplace_back(0, a, a);
}
auto lst = LazySegmentTree(v, std::make_tuple(0, -1ll, -1ll), 0ll);
while (q--) {
int t, l, r;
std::cin >> t >> l >> r;
l--;
if (t == 1) {
i64 x;
std::cin >> x;
lst.update(l, r, x);
} else {
std::cout << r - l - std::get<0>(lst.query(l, r)) << std::endl;
}
}
return 0;
}
lowr