結果
| 問題 |
No.230 Splarraay スプラレェーイ
|
| コンテスト | |
| ユーザー |
Jikky1618
|
| 提出日時 | 2024-09-29 18:19:44 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,957 bytes |
| コンパイル時間 | 3,100 ms |
| コンパイル使用メモリ | 259,596 KB |
| 実行使用メモリ | 10,112 KB |
| 最終ジャッジ日時 | 2024-09-29 18:34:43 |
| 合計ジャッジ時間 | 3,929 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 16 WA * 1 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#ifdef LOCAL
#include <debug_print.hpp>
#define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (static_cast<void>(0))
#endif
template <class T, class E, class F, class G, class H>
struct LazySegmentTree {
int n, len, height;
vector<T> data;
vector<E> lazy;
const F op;
const G mapp;
const H comp;
const T e;
const E id;
LazySegmentTree() = default;
LazySegmentTree(int size, const F& operation, const G& mapping, const H& composition, const T& identity,
const E& lazy_identity)
: n(size), op(operation), mapp(mapping), comp(composition), e(identity), id(lazy_identity) {
init();
}
LazySegmentTree(const vector<T>& v, const F& operation, const G& mapping, const H& composition, const T& identity,
const E& lazy_identity)
: n(int(v.size())), op(operation), mapp(mapping), comp(composition), e(identity), id(lazy_identity) {
init(), build(v);
}
void init() {
len = 1, height = 0;
while (len < n) len <<= 1, height++;
data.assign(len << 1, e);
lazy.assign(len << 1, id);
}
void build(const vector<T>& v) {
for (int i = 0; i < n; i++) data[i + len] = v[i];
for (int i = len - 1; i > 0; i--) data[i] = op(data[i << 1 | 0], data[i << 1 | 1]);
}
T reflect(int k) { return lazy[k] == id ? data[k] : mapp(data[k], lazy[k]); }
void eval(int k) {
if (lazy[k] == id) return;
// 子の要素があれば, 子に遅延配列の伝搬を行う
lazy[k << 1 | 0] = comp(lazy[k << 1 | 0], lazy[k]);
lazy[k << 1 | 1] = comp(lazy[k << 1 | 1], lazy[k]);
// 自身を更新
data[k] = reflect(k);
lazy[k] = id;
}
void recalc(int k) {
while (k >>= 1) data[k] = op(reflect(k << 1 | 0), reflect(k << 1 | 1));
}
void thrust(int k) {
for (int i = height; i > 0; i--) eval(k >> i);
}
// [l, r) に val を作用させて更新
void update(int l, int r, E val) {
if (l >= r) return;
// 上側のノードをまず伝搬
l += len, r += len;
thrust(l), thrust(r);
int l0 = l, r0 = r;
while (l < r) {
if (l & 1) lazy[l] = comp(lazy[l], val), l++;
if (r & 1) --r, lazy[r] = comp(lazy[r], val);
l >>= 1, r >>= 1;
}
l = l0, r = r0;
// 上側のノードを更新
recalc(l), recalc(r - 1);
}
// i 番目の値を val に更新
void set(int i, T val) {
i += len;
thrust(i);
data[i] = val;
lazy[i] = id;
recalc(i);
};
// [l, r) の区間取得
T prod(int l, int r) {
assert(0 <= l && l <= r && r <= n);
if (l >= r) return e;
l += len, r += len;
// 上側のノードをまず伝搬
thrust(l), thrust(r - 1);
T resl = e, resr = e;
while (l < r) {
if (l & 1) resl = op(resl, reflect(l++));
if (r & 1) resr = op(reflect(--r), resr);
l >>= 1, r >>= 1;
}
return op(resl, resr);
}
// i の値を取得
T get(int i) {
i += len;
for (int j = height; j > 0; j--) eval(i >> j);
return reflect(i);
}
T operator[](int i) { return get(i); }
T all_prod() const { return data[1]; }
};
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cout << fixed << setprecision(20);
int N, Q;
cin >> N >> Q;
vector<ll> A(N), B(N);
// {A の塗ったマス, B の塗ったマス, 区間長} を管理
using S = tuple<int, int, int>;
constexpr S e = {0, 0, 0};
auto op = [](S a, S b) -> S {
auto [a1, a2, a3] = a;
auto [b1, b2, b3] = b;
return {a1 + b1, a2 + b2, a3 + b3};
};
using F = int; // 1: A が塗った, -1: B が塗った
constexpr F id = 0;
auto mapping = [](S x, F f) -> S {
if (f == id) return x;
auto [x1, x2, x3] = x;
// f = 1 なら A が塗った, f = -1 なら B が塗った
return (f == 1 ? S{x3, 0, x3} : S{0, x3, x3});
};
auto composition = [](F f, F g) -> F { return g == id ? f : g; };
vector<S> V(N, {0, 0, 1});
LazySegmentTree seg(V, op, mapping, composition, e, id);
vector<ll> ans(2);
while (Q--) {
int x, l, r;
cin >> x >> l >> r, r++;
if (x == 0) {
auto [a, b, len] = seg.prod(l, r);
// 多いチームの方に加算
if (a > b) ans[0] += a;
if (b > a) ans[1] += b;
}
if (x == 1) {
seg.update(l, r, 1);
}
if (x == 2) {
seg.update(l, r, -1);
}
}
auto [a, b, len] = seg.all_prod();
ans[0] += a, ans[1] += b;
cout << ans[0] << " " << ans[1] << '\n';
}
Jikky1618