結果
問題 |
No.3208 Parse AND OR Affection
|
ユーザー |
|
提出日時 | 2025-06-02 01:16:21 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 428 ms / 5,000 ms |
コード長 | 6,084 bytes |
コンパイル時間 | 1,364 ms |
コンパイル使用メモリ | 112,852 KB |
実行使用メモリ | 52,144 KB |
最終ジャッジ日時 | 2025-06-02 01:16:29 |
合計ジャッジ時間 | 8,197 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 20 |
ソースコード
#include <iostream> #include <vector> #include <string> #include <cassert> #include <functional> namespace atcoder { namespace internal { #if __cplusplus >= 202002L using std::bit_ceil; #else // @return same with std::bit::bit_ceil unsigned int bit_ceil(unsigned int n) { unsigned int x = 1; while (x < (unsigned int)(n)) x *= 2; return x; } #endif // @param n `1 <= n` // @return same with std::bit::countr_zero int countr_zero(unsigned int n) { #ifdef _MSC_VER unsigned long index; _BitScanForward(&index, n); return index; #else return __builtin_ctz(n); #endif } // @param n `1 <= n` // @return same with std::bit::countr_zero constexpr int countr_zero_constexpr(unsigned int n) { int x = 0; while (!(n & (1 << x))) x++; return x; } } // namespace internal } // namespace atcoder namespace atcoder { #if __cplusplus >= 201703L template <class S, auto op, auto e> struct segtree { static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>, "op must work as S(S, S)"); static_assert(std::is_convertible_v<decltype(e), std::function<S()>>, "e must work as S()"); #else template <class S, S (*op)(S, S), S (*e)()> struct segtree { #endif public: segtree() : segtree(0) {} explicit segtree(int n) : segtree(std::vector<S>(n, e())) {} explicit segtree(const std::vector<S>& v) : _n(int(v.size())) { size = (int)internal::bit_ceil((unsigned int)(_n)); log = internal::countr_zero((unsigned int)size); d = std::vector<S>(2 * size, e()); for (int i = 0; i < _n; i++) d[size + i] = v[i]; for (int i = size - 1; i >= 1; i--) { update(i); } } void set(int p, S x) { assert(0 <= p && p < _n); p += size; d[p] = x; for (int i = 1; i <= log; i++) update(p >> i); } S get(int p) const { assert(0 <= p && p < _n); return d[p + size]; } S prod(int l, int r) const { assert(0 <= l && l <= r && r <= _n); S sml = e(), smr = e(); l += size; r += size; while (l < r) { if (l & 1) sml = op(sml, d[l++]); if (r & 1) smr = op(d[--r], smr); l >>= 1; r >>= 1; } return op(sml, smr); } S all_prod() const { return d[1]; } template <bool (*f)(S)> int max_right(int l) const { return max_right(l, [](S x) { return f(x); }); } template <class F> int max_right(int l, F f) const { assert(0 <= l && l <= _n); assert(f(e())); if (l == _n) return _n; l += size; S sm = e(); do { while (l % 2 == 0) l >>= 1; if (!f(op(sm, d[l]))) { while (l < size) { l = (2 * l); if (f(op(sm, d[l]))) { sm = op(sm, d[l]); l++; } } return l - size; } sm = op(sm, d[l]); l++; } while ((l & -l) != l); return _n; } template <bool (*f)(S)> int min_left(int r) const { return min_left(r, [](S x) { return f(x); }); } template <class F> int min_left(int r, F f) const { assert(0 <= r && r <= _n); assert(f(e())); if (r == 0) return 0; r += size; S sm = e(); do { r--; while (r > 1 && (r % 2)) r >>= 1; if (!f(op(d[r], sm))) { while (r < size) { r = (2 * r + 1); if (f(op(d[r], sm))) { sm = op(d[r], sm); r--; } } return r + 1 - size; } sm = op(d[r], sm); } while ((r & -r) != r); return 0; } private: int _n, size, log; std::vector<S> d; void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); } }; } // namespace atcoder template<int I> struct Matrix { // Size = I long long A[I][I]; Matrix(void) { for(int i = 0; i < I; ++i) { for(int j = 0; j < I; ++j) { A[i][j] = 0; } } } Matrix(std::vector<std::vector<int>>& arr) { for(int i = 0; i < I; ++i) { for(int j = 0; j < I; ++j) { A[i][j] = arr[i][j]; } } } }; template<int I> Matrix<I> mul(Matrix<I> A, Matrix<I> B) { Matrix<I> r; for(int i = 0; i < I; ++i) { for(int j = 0; j < I; ++j) { for(int k = 0; k < I; ++k) { r.A[i][j] += A.A[i][k] * B.A[k][j]; } } } return r; } template<int I> Matrix<I> E(void) { Matrix<I> e; for(int i = 0; i < I; ++i) { e.A[i][i] = 1; } return e; } int main() { int N, Q; std::cin >> N >> Q; std::string S; std::cin >> S; S = '+' + S; std::vector<Matrix<4>> matrix(S.size() / 2); for(int i = 0; i < (int)S.size() / 2; ++i) { char op = S[2 * i + 0], tf = S[2 * i + 1]; if(op == '+' && tf == 'T') { if(tf == 'T') { matrix[i].A[0][1] = 1; matrix[i].A[1][1] = 1; } } else if(op == '*' && tf == 'F') { if(tf == 'F') { matrix[i].A[0][0] = 1; matrix[i].A[1][0] = 1; } } else if(op == '^' && tf == 'T') { if(tf == 'T') { matrix[i].A[0][1] = 1; matrix[i].A[1][0] = 1; } } else { matrix[i].A[0][0] = 1; matrix[i].A[1][1] = 1; } if(tf == 'T') matrix[i].A[2][1] = 1; if(tf == 'F') matrix[i].A[2][0] = 1; matrix[i].A[1][3] = 1; matrix[i].A[2][2] = 1; matrix[i].A[3][3] = 1; } atcoder::segtree<Matrix<4>, mul<4>, E<4>> seg(matrix); for(int t = 0; t < Q; ++t) { int L, R; std::cin >> L >> R; auto result = seg.prod(L / 2, R / 2 + 1); std::cout << result.A[2][1] + result.A[2][3] << std::endl; } }