結果

問題 No.1802 Range Score Query for Bracket Sequence
ユーザー Forested
提出日時 2022-01-07 12:04:30
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 450 ms / 2,000 ms
コード長 4,066 bytes
コンパイル時間 764 ms
コンパイル使用メモリ 75,900 KB
最終ジャッジ日時 2025-01-27 08:58:10
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 1
other AC * 24
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <string>
#include <iostream>

// ===== fenwick_tree.hpp =====
#ifndef FENWICK_TREE_HPP
#define FENWICK_TREE_HPP

#include <cassert>
#include <vector>

// ===== operations.hpp =====
#ifndef OPERATIONS_HPP
#define OPERATIONS_HPP

#include <limits>
#include <utility>

template <typename T>
struct Add {
    using Value = T;
    static Value id() {
        return T(0);
    }
    static Value op(const Value &lhs, const Value &rhs) {
        return lhs + rhs;
    }
    static Value inv(const Value &x) {
        return -x;
    }
};

template <typename T>
struct Mul {
    using Value = T;
    static Value id() {
        return Value(1);
    }
    static Value op(const Value &lhs, const Value &rhs) {
        return lhs * rhs;
    }
    static Value inv(const Value &x) {
        return Value(1) / x;
    }
};

template <typename T>
struct Min {
    using Value = T;
    static Value id() {
        return std::numeric_limits<T>::max();
    }
    static Value op(const Value &lhs, const Value &rhs) {
        return std::min(lhs, rhs);
    }
};

template <typename T>
struct Max {
    using Value = T;
    static Value id() {
        return std::numeric_limits<Value>::min();
    }
    static Value op(const Value &lhs, const Value &rhs) {
        return std::max(lhs, rhs);
    }
};

template <typename T>
struct Xor {
    using Value = T;
    static Value id() {
        return T(0);
    }
    static Value op(const Value &lhs, const Value &rhs) {
        return lhs ^ rhs;
    }
    static Value inv(const Value &x) {
        return x;
    }
};

template <typename Monoid>
struct Reversible {
    using Value = std::pair<typename Monoid::Value, typename Monoid::Value>;
    static Value id() {
        return Value(Monoid::id(), Monoid::id());
    }
    static Value op(const Value &v1, const Value &v2) {
        return Value(
            Monoid::op(v1.first, v2.first),
            Monoid::op(v2.second, v1.second));
    }
};

#endif
// ===== operations.hpp =====

template <typename CommutativeGroup>
class FenwickTree {
public:
    using Value = typename CommutativeGroup::Value;

private:
    std::vector<Value> data;

public:
    FenwickTree(std::size_t n) : data(n, CommutativeGroup::id()) {}

    void add(std::size_t idx, const Value &x) {
        assert(idx < data.size());
        for (; idx < data.size(); idx |= idx + 1) {
            data[idx] = CommutativeGroup::op(data[idx], x);
        }
    }

    Value sum(std::size_t r) const {
        assert(r <= data.size());
        Value ret = CommutativeGroup::id();
        for (; r > 0; r &= r - 1) {
            ret = CommutativeGroup::op(ret, data[r - 1]);
        }
        return ret;
    }

    Value sum(std::size_t l, std::size_t r) const {
        assert(l <= r && r <= data.size());
        return CommutativeGroup::op(sum(r), CommutativeGroup::inv(sum(l)));
    }
};

#endif
// ===== fenwick_tree.hpp =====

int main() {
    std::size_t n, q;
    std::cin >> n >> q;
    std::string s;
    std::cin >> s;
    
    FenwickTree<Add<std::size_t>> fw(n - 1);
    for (std::size_t i = 0; i < n - 1; ++i) {
        if (s[i] == '(' && s[i + 1] == ')') {
            fw.add(i, 1);
        }
    }
    
    for (std::size_t qi = 0; qi < q; ++qi) {
        std::size_t type;
        std::cin >> type;
        if (type == 1) {
            std::size_t i;
            std::cin >> i;
            --i;
            if (i != 0 && s[i - 1] == '(' && s[i] == ')') {
                fw.add(i - 1, - (std::size_t) 1);
            }
            if (i != n - 1 && s[i] == '(' && s[i + 1] == ')') {
                fw.add(i, - (std::size_t) 1);
            }
            s[i] ^= '(' ^ ')';
            if (i != 0 && s[i - 1] == '(' && s[i] == ')') {
                fw.add(i - 1, 1);
            }
            if (i != n - 1 && s[i] == '(' && s[i + 1] == ')') {
                fw.add(i, 1);
            }
        } else {
            std::size_t l, r;
            std::cin >> l >> r;
            --l;
            std::size_t ans = fw.sum(l, r - 1);
            std::cout << ans << '\n';
        }
    }
}
0