結果

問題 No.3208 Parse AND OR Affection
ユーザー amesyu
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #

#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;
    }
}
0