#line 1 "test/yukicoder/230.test.cpp" #define PROBLEM "https://yukicoder.me/problems/no/230" #line 2 "template.hpp" // #pragma GCC target("avx2") // #pragma GCC optimize("O3") // #pragma GCC optimize("unroll-loops") #include using namespace std; // https://xn--kst.jp/blog/2019/08/29/cpp-comp/ // debug methods // usage: debug(x,y); // vector 出力できるように修正 template ostream& debug_print(ostream& os, const vector& v) { os << "["; for (size_t i = 0; i < v.size(); ++i) { os << v[i]; if (i < v.size() - 1) os << ", "; } os << "]"; return os; } template ostream& debug_print(ostream& os, const T& var) { os << var; return os; } #define CHOOSE(a) CHOOSE2 a #define CHOOSE2(a0, a1, a2, a3, a4, x, ...) x #define debug_1(x1) { cout << #x1 << ": "; debug_print(cout, x1) << endl; } #define debug_2(x1, x2) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << endl; } #define debug_3(x1, x2, x3) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << ", " << #x3 << ": "; debug_print(cout, x3) << endl; } #define debug_4(x1, x2, x3, x4) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << ", " << #x3 << ": "; debug_print(cout, x3) << ", " << #x4 << ": "; debug_print(cout, x4) << endl; } #define debug_5(x1, x2, x3, x4, x5) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << ", " << #x3 << ": "; debug_print(cout, x3) << ", " << #x4 << ": "; debug_print(cout, x4) << ", " << #x5 << ": "; debug_print(cout, x5) << endl; } #ifdef LOCAL #define debug(...) CHOOSE((__VA_ARGS__, debug_5, debug_4, debug_3, debug_2, debug_1, ~))(__VA_ARGS__) #else #define debug(...) #endif using ll = long long; using vl = vector; using Graph = vector>; using P = pair; #define all(v) v.begin(), v.end() template inline bool chmax(T &a, T b) { return ((a < b) ? (a = b, true) : (false)); } template inline bool chmin(T &a, T b) { return ((a > b) ? (a = b, true) : (false)); } #define rep1(i, n) for(ll i = 1; i <= ((ll)n); ++i) // https://trap.jp/post/1224/ template constexpr auto min(T... a) { return min(initializer_list>{a...}); } template constexpr auto max(T... a) { return max(initializer_list>{a...}); } template void input(T &...a) { (cin >> ... >> a); } template void input(vector &a) { for(T &x : a) cin >> x; } void print() { cout << '\n'; } template void print(const T &a, const Ts &...b) { cout << a; (cout << ... << (cout << ' ', b)); cout << '\n'; } void print(const string &s) { cout << s << '\n'; } template struct is_container : std::false_type {}; template struct is_container().begin()), decltype(std::declval().end())>> : std::true_type {}; template typename enable_if::value>::type print(const Container& x) { if (!x.empty()) { auto it = x.begin(); for (; it != prev(x.end()); ++it) { cout << *it << " "; } cout << *it << "\n"; // 最後の要素を出力して改行 } } #define INT(...) \ int __VA_ARGS__; \ input(__VA_ARGS__) #define LL(...) \ long long __VA_ARGS__; \ input(__VA_ARGS__) #define STR(...) \ string __VA_ARGS__; \ input(__VA_ARGS__) #define REP1(a) for(ll i = 0; i < a; i++) #define REP2(i, a) for(ll i = 0; i < a; i++) #define REP3(i, a, b) for(ll i = a; i < b; i++) #define REP4(i, a, b, c) for(ll i = a; i < b; i += c) #define overload4(a, b, c, d, e, ...) e #define rep(...) overload4(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__) ll inf = 3e18; vl dx = {1, -1, 0, 0}; vl dy = {0, 0, 1, -1}; #line 2 "data_structure/lazy_segtree.hpp" template // composition(f,g)(x) = f∘g(x) = f(g(x)) // aclと同じ、maspyさん記事と逆 struct lazy_segtree { vector v; vector vf; ll n; lazy_segtree(ll n) : n(n), v(vector(2 * n, e())), vf(vector(2 * n, id())) {}; lazy_segtree(vector v_) : n(v_.size()) { vf = vector(2 * n, id()); v = vector(2 * n, e()); rep(i, n) { v[i + n] = v_[i]; } for(ll i = n - 1; i > 0; i--) { v[i] = op(v[i << 1], v[i << 1 | 1]); } } void apply(ll l, ll r, F f) { l += n; r += n; ll l0 = l / (l & -l); ll r0 = r / (r & -r) - 1; propagate_above(l0); propagate_above(r0); while(l < r) { if(l & 1) { // vf[l] = composition(f, vf[l]); apply_at(l,f); l++; } if(r & 1) { r--; // vf[r] = composition(f, vf[r]); apply_at(r,f); } l >>= 1; r >>= 1; } recul_above(l0); recul_above(r0); } S get(ll x) { x += n; ll maxi = bit_length(x) - 1; for(ll i = maxi; i > 0; i--) { propagate_at(x >> i); } return mapping(vf[x], v[x]); } void set(ll x, S s) { x += n; propagate_above(x); v[x] = s; vf[x] = id(); recul_above(x); } S prod(ll l, ll r) { l += n; r += n; ll l0 = l / (l & -l); ll r0 = r / (r & -r) - 1; propagate_above(l0); propagate_above(r0); S sl = e(), sr = e(); while(l < r) { if(l & 1) { debug(vf[l].f); sl = op(sl, mapping(vf[l], v[l])); l++; } if(r & 1) { r--; sr = op(mapping(vf[r], v[r]), sr); } l >>= 1; r >>= 1; } return op(sl, sr); } private: S eval_at(ll x) { return mapping(vf[x], v[x]); } void apply_at(ll x, F f) { v[x] = mapping(f, v[x]); vf[x] = composition(f, vf[x]); } void propagate_at(ll x) { apply_at(x << 1, vf[x]); apply_at(x << 1 | 1, vf[x]); vf[x] = id(); // v[x] = mapping(vf[x], v[x]); // vf[x << 1] = composition(vf[x], vf[x << 1]); // vf[x << 1 | 1] = composition(vf[x], vf[x << 1 | 1]); // vf[x] = id(); } ll bit_length(unsigned long long x) { return 64 - countl_zero(x); } void propagate_above(ll x) { ll maxi = bit_length(x) - 1; for(ll i = maxi; i > 0; i--) { propagate_at(x >> i); } return; } void recul_above(ll x) { while(x > 1) { x >>= 1; v[x] = op(eval_at(x << 1), eval_at(x << 1 | 1)); } } }; #line 4 "test/yukicoder/230.test.cpp" struct S { ll a, b, sz; }; struct F { ll f; // 0 e,1 a,2 b }; S op(S s, S t) { return S(s.a + t.a, s.b + t.b, s.sz + t.sz); } S mapping(F f, S s) { if(f.f == 0) { return s; } else if(f.f == 1) { return S(s.sz, 0, s.sz); } else { return S(0, s.sz, s.sz); } } F composition(F f, F g) { if(f.f == 0) { return g; } else return f; } S e() { return S(0, 0, 0); } F id() { return F(0); } void solve() { LL(n, q); lazy_segtree seg( vector(n, S(0, 0, 1))); ll ans_a = 0, ans_b = 0; // rep(i, n) { seg.set(i, S(0, 0, 1)); } rep(_, q) { LL(x, l, r); if(x == 0) { S res = seg.prod(l, r + 1); if(res.a > res.b) { ans_a += res.a; } else if(res.a < res.b) { ans_b += res.b; } } else if(x == 1) { seg.apply(l, r + 1, F(1)); } else { seg.apply(l, r + 1, F(2)); } } { S res = seg.prod(0, n); ans_a += res.a; ans_b += res.b; } print(ans_a, ans_b); } int main() { ios::sync_with_stdio(false); std::cin.tie(nullptr); solve(); }