#include #include #include #include #include class LazySegTree { public: static std::tuple X_unit; // (0, 0, 0) 無色、色1、色2 static int A_unit; static std::tuple X_f(std::tuple x, std::tuple y) { int a, b, c, d, e, f; std::tie(a, b, c) = x; std::tie(d, e, f) = y; return std::make_tuple(a + d, b + e, c + f); } static int A_f(int x, int y) { if (y == 0) return x; return y; } static std::tuple operate(std::tuple x, int y) { if (y == 0) return x; int s = std::get<0>(x) + std::get<1>(x) + std::get<2>(x); if (y == 1) return std::make_tuple(0, s, 0); else return std::make_tuple(0, 0, s); } LazySegTree(int N) : N(N), X(N + N, X_unit), A(N + N, A_unit) {} void build(std::vector>& seq) { for (int i = 0; i < seq.size(); ++i) { X[i + N] = seq[i]; } for (int i = N - 1; i > 0; --i) { X[i] = X_f(X[i << 1], X[i << 1 | 1]); } } std::tuple _eval_at(int i) { return operate(X[i], A[i]); } void _propagate_at(int i) { X[i] = _eval_at(i); A[i << 1] = A_f(A[i << 1], A[i]); A[i << 1 | 1] = A_f(A[i << 1 | 1], A[i]); A[i] = A_unit; } void _propagate_above(int i) { int H = std::log2(i) + 1; for (int h = H; h > 0; --h) { _propagate_at(i >> h); } } void _recalc_above(int i) { while (i > 1) { i >>= 1; X[i] = X_f(_eval_at(i << 1), _eval_at(i << 1 | 1)); } } void set_val(int i, std::tuple x) { i += N; _propagate_above(i); X[i] = x; A[i] = A_unit; _recalc_above(i); } std::tuple fold(int L, int R) { L += N; R += N; _propagate_above(L / (L & -L)); _propagate_above(R / (R & -R) - 1); auto vL = X_unit; auto vR = X_unit; while (L < R) { if (L & 1) { vL = X_f(vL, _eval_at(L)); ++L; } if (R & 1) { --R; vR = X_f(_eval_at(R), vR); } L >>= 1; R >>= 1; } return X_f(vL, vR); } void operate_range(int L, int R, int x) { L += N; R += N; int L0 = L / (L & -L); int R0 = R / (R & -R) - 1; _propagate_above(L0); _propagate_above(R0); while (L < R) { if (L & 1) { A[L] = A_f(A[L], x); ++L; } if (R & 1) { --R; A[R] = A_f(A[R], x); } L >>= 1; R >>= 1; } _recalc_above(L0); _recalc_above(R0); } private: int N; std::vector> X; std::vector A; }; std::tuple LazySegTree::X_unit = std::make_tuple(0, 0, 0); int LazySegTree::A_unit = 0; int main() { int N, Q; std::cin >> N >> Q; LazySegTree seg(N); std::vector> seq(N, std::make_tuple(1, 0, 0)); seg.build(seq); int score_A = 0, score_B = 0; for (int i = 0; i < Q; ++i) { int x, L, R; std::cin >> x >> L >> R; ++R; if (x == 0) { auto [_, a, b] = seg.fold(L, R); if (a > b) { score_A += a; } else if (b > a) { score_B += b; } } else { seg.operate_range(L, R, x); } } auto [_, a, b] = seg.fold(0, N); std::cout << score_A + a << " " << score_B + b << std::endl; return 0; }