結果
問題 | No.1802 Range Score Query for Bracket Sequence |
ユーザー | bowwowforeach |
提出日時 | 2022-01-08 00:05:44 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 116 ms / 2,000 ms |
コード長 | 18,873 bytes |
コンパイル時間 | 2,213 ms |
コンパイル使用メモリ | 215,744 KB |
実行使用メモリ | 7,740 KB |
最終ジャッジ日時 | 2024-06-30 02:19:00 |
合計ジャッジ時間 | 4,774 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 97 ms
7,692 KB |
testcase_02 | AC | 97 ms
7,704 KB |
testcase_03 | AC | 98 ms
7,640 KB |
testcase_04 | AC | 99 ms
7,632 KB |
testcase_05 | AC | 99 ms
7,596 KB |
testcase_06 | AC | 104 ms
7,696 KB |
testcase_07 | AC | 106 ms
7,648 KB |
testcase_08 | AC | 98 ms
7,468 KB |
testcase_09 | AC | 98 ms
7,740 KB |
testcase_10 | AC | 99 ms
7,624 KB |
testcase_11 | AC | 85 ms
7,612 KB |
testcase_12 | AC | 80 ms
7,492 KB |
testcase_13 | AC | 82 ms
7,700 KB |
testcase_14 | AC | 116 ms
7,640 KB |
testcase_15 | AC | 2 ms
6,940 KB |
testcase_16 | AC | 2 ms
6,944 KB |
testcase_17 | AC | 2 ms
6,944 KB |
testcase_18 | AC | 2 ms
6,944 KB |
testcase_19 | AC | 2 ms
6,940 KB |
testcase_20 | AC | 2 ms
6,940 KB |
testcase_21 | AC | 1 ms
6,944 KB |
testcase_22 | AC | 1 ms
6,940 KB |
testcase_23 | AC | 2 ms
6,940 KB |
testcase_24 | AC | 2 ms
6,940 KB |
ソースコード
#define _USE_MATH_DEFINES #include <bits/stdc++.h> using namespace std; #define FOR(i, s, e) for (int i = int(s); i < int(e); ++i) #define RFOR(i, s, e) for (int i = int(e) - 1; i >= int(s); --i) #define REP(i, n) for (int i = 0, i##_size = int(n); i < i##_size; ++i) #define RREP(i, n) for (int i = int(n) - 1; i >= 0; --i) #define ALL(x) (x).begin(),(x).end() #define rep(i, n) for (int i = 0, i##_size = int(n); i < i##_size; ++i) #define rrep(i, n) for (int i = int(n) - 1; i >= 0; --i) #define all(x) (x).begin(),(x).end() template <class T> inline void chmin(T& a, T b) { if (b < a) { a = b; } } template <class T> inline void chmax(T& a, T b) { if (a < b) { a = b; } } template <class T> inline constexpr T square(T v) { return v * v; } template <class T, class... Params> void InstanceRun(Params&&... params) { T* m = new T; m->Run(forward<Params>(params)...); } struct Main; int main(int argc, const char* argv[]) { cin.tie(0); ios::sync_with_stdio(0); InstanceRun<Main>(argc, argv); } using ll = long long; #define int ll #define INF INT64_MAX template <class T> struct arr : public vector<T> { static arr<arr<T>> D2(int y, int x, T value) { return arr<arr<T>>(y, arr<T>(x, value)); } static arr<arr<arr<T>>> D3(int z, int y, int x, T value) { return arr<arr<arr<T>>>(z, arr<arr<T>>(y, arr<T>(x, value))); } static arr<T> Iota(int N, int value = 0) { auto r = arr<T>(N); r.iota(value); return r; } arr() {} arr(initializer_list<T> il) : vector<T>(il) {} explicit arr(int n) : vector<T>(n) {} arr(int n, T v) : vector<T>(n, v) {} arr(const arr& r) : vector<T>(r) {} arr(arr&& r) : vector<T>(move(r)) {} arr& operator = (const arr& r) { vector<T>::operator = (r); return *this; } arr& operator = (arr&& r) { vector<T>::operator = (move(r)); return *this; } T& operator()(int i) { return (*this)[i]; } T const& operator()(int i) const { return (*this)[i]; } void init(int n, T v = T()) { this->assign(n, v); } int sz() const { return (int)this->size(); } void pb(T v) { this->push_back(v); } void sort() { std::sort(this->begin(), this->end()); } template <class F> void sort(F&& f) { std::sort(this->begin(), this->end(), f); } void rsort() { std::sort(this->begin(), this->end(), greater<T>()); } void reverse() { std::reverse(this->begin(), this->end()); } void unique_erase() { this->erase(std::unique(this->begin(), this->end()), this->end()); } bool next_permutation() { return std::next_permutation(this->begin(), this->end()); } int lower_bound(T const& v, function<bool(T, T)> p) { return std::lower_bound(this->begin(), this->end(), v, p) - this->begin(); } int lower_bound(T const& v) { return std::lower_bound(this->begin(), this->end(), v) - this->begin(); } int upper_bound(T const& v, function<bool(T, T)> p) { return std::upper_bound(this->begin(), this->end(), v, p) - this->begin(); } int upper_bound(T const& v) { return std::upper_bound(this->begin(), this->end(), v) - this->begin(); } void iota(T startValue = 0) { ::iota(this->begin(), this->end(), startValue); } void fill(T v) { ::fill(this->begin(), this->end(), v); } int find_sorted_nearest(T const& v) { int i = this->lower_bound(v); if (i >= sz()) { --i; } else if ((*this)[i] != v) { int p = i - 1; if (p >= 0) { int id = abs((*this)[i] - v); int pd = abs((*this)[p] - v); if (pd < id) { i = p; } } } return i; } int find_sorted(T const& v) { int i = this->lower_bound(v); if (i >= sz()) { return -1; } if ((*this)[i] != v) { return -1; } return i; } int find(T const& v) const { auto it = std::find(this->begin(), this->end(), v); if (it == this->end()) { return -1; } return it - this->begin(); } bool is_contains(T const& v) const { auto it = std::find(this->begin(), this->end(), v); if (it == this->end()) { return false; } return true; } template <class P> void remove_if_erase(P&& predicate) { this->erase(std::remove_if(this->begin(), this->end(), predicate), this->end()); } T& emplace_back_ref() { this->emplace_back(); return this->back(); } friend ostream& operator<<(ostream& os, const arr<T>& p) { if (p.empty()) { return os; } os << p[0]; FOR(i, 1, p.size()) { os << " " << p[i]; } return os; } }; using ints = arr<int>; template <class A, class B> struct pr { union { A a; A key; A first; A x; }; union { B b; B value; B second; B y; }; bool operator == (pr const& r) const { return a == r.a && b == r.b; } bool operator != (pr const& r) const { return !((*this) == r); } bool operator < (pr const& r) const { if (a == r.a) { return b < r.b; } return a < r.a; } pr& operator += (pr const& v) { a += v.a; b += v.b; return *this; } pr& operator -= (pr const& v) { a -= v.a; b -= v.b; return *this; } pr operator + (pr const& v) const { return pr{ a, b } += v; } pr operator - (pr const& v) const { return pr{ a, b } -= v; } pr operator - () const { return pr{ -a, -b }; } template <class C, class D> operator pr<C, D>() const { return { C(a), D(b) }; } template <class T> auto operator * (T const& v) const -> pr<decltype(x * v), decltype(y * v)> { return { x * v, y * v }; } template <class T> auto operator / (T const& v) const -> pr<decltype(x / v), decltype(y / v)> { return { x / v, y / v }; } template <class T> pr& operator *= (T const& v) { x *= v; y *= v; return *this; } template <class T> pr& operator /= (T const& v) { x /= v; y /= v; return *this; } void flip() { swap(x, y); } friend istream& operator>>(istream& is, pr& p) { is >> p.a >> p.b; return is; } friend ostream& operator<<(ostream& os, pr const& p) { os << p.a << " " << p.b; return os; } }; using pint = pr<int, int>; using pdouble = pr<double, double>; static_assert(is_pod<pint>::value, "not pod"); template <class A, class B, class C> struct tr { union { A a; A first; A x; }; union { B b; B second; B y; }; union { C c; C third; C z; }; bool operator == (tr const& r) const { return a == r.a && b == r.b && c == r.c; } bool operator != (tr const& r) const { return !((*this) == r); } bool operator < (tr const& r) const { if (a == r.a) { if (b == r.b) { return c < r.c; } return b < r.b; } return a < r.a; } tr operator + (tr v) const { return tr(x, y, z) += v; } tr operator - (tr v) const { return tr(x, y, z) -= v; } tr operator - () const { return tr{ -x, -y, -z }; } tr& operator += (tr v) { x += v.x; y += v.y; z += v.z; return *this; } tr& operator -= (tr v) { x -= v.x; y -= v.y; z -= v.z; return *this; } friend istream& operator>>(istream& is, tr& p) { is >> p.a >> p.b >> p.c; return is; } friend ostream& operator<<(ostream& os, tr const& p) { os << p.a << " " << p.b << " " << p.c; return os; } }; using tint = tr<int, int, int>; static_assert(is_pod<tint>::value, "not pod"); template <class T> struct arr2 { vector<vector<T>> m_vec; int m_width; int m_height; arr2() : m_width(0), m_height(0) {} arr2(int w, int h, T const& value = T()) : m_width(w), m_height(h) { m_vec.resize(h, vector<T>(w, value)); } arr2(arr2 const& r) { m_vec = r.m_vec; m_width = r.m_width; m_height = r.m_height; } arr2(arr2&& r) { m_vec = move(r.m_vec); m_width = r.m_width; m_height = r.m_height; } arr2& operator=(arr2 const& r) { m_vec = r.m_vec; m_width = r.m_width; m_height = r.m_height; return *this; } arr2& operator=(arr2&& r) { m_vec = move(r.m_vec); m_width = r.m_width; m_height = r.m_height; return *this; } bool operator ==(arr2 const& r) const { return m_vec == r.m_vec; } bool operator <(arr2 const& r) const { if (m_width != r.m_width) { return m_width < r.m_width; } if (m_height != r.m_height) { return m_height < r.m_height; } REP(y, m_height) { REP(x, m_width) { if ((*this)(x, y) != r(x, y)) { return (*this)(x, y) < r(x, y); } } } return false; } pint size() const { return pint{ m_width, m_height }; } int width() const { return m_width; } int height() const { return m_height; } void clear() { m_vec.clear(); m_width = 0; m_height = 0; } void init(int w, int h, T const& value = T()) { m_vec.clear(); m_vec.resize(h, vector<T>(w, value)); m_width = w; m_height = h; } void init(pint size, T const& value = T()) { init(size.x, size.y, value); } #if VALIDATION void CheckOutOfRange(int x, int y) const { if (x < 0 || y < 0 || x >= m_width || y >= m_height) { VALIDATE_ABORT(); } } void CheckOutOfRange(const pint& p) const { if (p.x < 0 || p.y < 0 || p.x >= m_width || p.y >= m_height) { VALIDATE_ABORT(); } } #endif T& operator()(int x, int y) { #if VALIDATION CheckOutOfRange(x, y); #endif return m_vec[y][x]; } T const& operator()(int x, int y) const { #if VALIDATION CheckOutOfRange(x, y); #endif return m_vec[y][x]; } T& operator()(pint p) { #if VALIDATION CheckOutOfRange(p); #endif return m_vec[p.y][p.x]; } T const& operator()(pint p) const { #if VALIDATION CheckOutOfRange(p); #endif return m_vec[p.y][p.x]; } T& operator[](pint p) { #if VALIDATION CheckOutOfRange(p); #endif return m_vec[p.y][p.x]; } T const& operator[](pint p) const { #if VALIDATION CheckOutOfRange(p); #endif return m_vec[p.y][p.x]; } vector<T>& operator[](int row) { #if VALIDATION if (row < 0 || row >= m_height) { VALIDATE_ABORT(); } #endif return m_vec[row]; } vector<T> const& operator[](int row) const { #if VALIDATION if (row < 0 || row >= m_height) { VALIDATE_ABORT(); } #endif return m_vec[row]; } bool isIn(int x, int y) const { return x >= 0 && x < m_width&& y >= 0 && y < m_height; } bool isIn(pint p) const { return isIn(p.x, p.y); } bool isOut(int x, int y) const { return x < 0 || x >= m_width || y < 0 || y >= m_height; } bool isOut(pint p) const { return isOut(p.x, p.y); } void disp(ostream& os, int w = 2) { REP(y, m_height) { REP(x, m_width) { os << setw(w) << (*this)(x, y) << " "; } os << endl; } os << endl; } }; template <class K, class V> struct dic : public map<K, V> { bool get(K const& k, V* v) const { auto it = this->find(k); if (it != this->end()) { *v = it->second; return true; } return false; } typename map<K, V>::const_iterator find_less_than_equal(const K& k) const { auto it = this->lower_bound(k); if (it == this->end()) { if (it == this->begin()) { return this->end(); } return prev(it); } else if (it->first == k) { return it; } else { if (it == this->begin()) { return this->end(); } return prev(it); } } typename map<K, V>::const_iterator find_greater_than_equal(const K& k) const { return this->lower_bound(k); } }; struct PrintStream { ostream& os_; bool printed_ = false; string space_ = " "; PrintStream(ostream& os, const string& space = " ") : os_(os), space_(space) { } template <class T> friend PrintStream& operator<<(PrintStream& ps, T&& v) { if (ps.printed_) { ps.os_ << ps.space_ << v; } else { ps.os_ << v; ps.printed_ = true; } return ps; } PrintStream& operator <<(PrintStream& (*manip)(PrintStream&)) { return (*manip)(*this); } }; PrintStream& endl(PrintStream& ps) { ps.os_ << '\n'; ps.printed_ = false; return ps; } struct OutputStream { ostream& os_; OutputStream(ostream& os) : os_(os) { } template <class T> friend OutputStream& operator<<(OutputStream& s, T const& v) { s.os_ << v << '\n'; return s; } }; #include <cstdint> using u8 = uint8_t; using u16 = uint16_t; using u32 = uint32_t; using u64 = uint64_t; using s8 = int8_t; using s16 = int16_t; using s32 = int32_t; using s64 = int64_t; using ints = arr<int>; using pint = pr<int, int>; using pints = arr<pint>; using tint = tr<int, int, int>; using tints = arr<tint>; using int2 = arr2<int>; const pints around4 = { pint{-1, 0}, pint{0, -1}, pint{1, 0}, pint{0, 1} }; constexpr int gcd(int a, int b) { if (a < 0) { a = -a; } if (b < 0) { b = -b; } if (a == 0) { return b; } if (b == 0) { return a; } while (int c = a % b) { a = b; b = c; } return b; } constexpr int lcm(int a, int b) { return a / gcd(a, b) * b; } int popcount(int v) { return bitset<64>(v).count(); } int64_t msb(int64_t v) { if (v == 0) return false; v |= (v >> 1); v |= (v >> 2); v |= (v >> 4); v |= (v >> 8); v |= (v >> 16); v |= (v >> 32); return popcount(v) - 1; } #ifdef LOCAL_TEST stringstream inputStream; stringstream outputStream; stringstream errorStream; istream& mis = inputStream; ostream& mos = outputStream; ostream& mes = errorStream; #else istream& mis = cin; ostream& mos = cout; ostream& mes = cerr; #endif template <class T> struct TypeInput; template <> struct TypeInput<int> { static void input(int& v, istream& is) { is >> v; } static void input(int& v, istream& is, int add) { is >> v; v += add; } }; template <> struct TypeInput<double> { static void input(int& v, istream& is) { is >> v; } }; template <> struct TypeInput<char> { static void input(char& v, istream& is) { is >> v; } }; template <> struct TypeInput<string> { static void input(string& v, istream& is) { is >> v; } }; template <class A, class B> struct TypeInput<pr<A, B>> { static void input(pr<A, B>& v, istream& is) { TypeInput<A>::input(v.a, is); TypeInput<B>::input(v.b, is); } static void input(pr<A, B>& v, istream& is, A&& addA, B&& addB) { TypeInput<A>::input(v.a, is, addA); TypeInput<B>::input(v.b, is, addB); } }; template <class A, class B, class C> struct TypeInput<tr<A, B, C>> { static void input(tr<A, B, C>& v, istream& is) { TypeInput<A>::input(v.a, is); TypeInput<B>::input(v.b, is); TypeInput<C>::input(v.c, is); } static void input(tr<A, B, C>& v, istream& is, A&& addA, B&& addB, C&& addC) { TypeInput<A>::input(v.a, is, addA); TypeInput<B>::input(v.b, is, addB); TypeInput<C>::input(v.c, is, addC); } }; template <class T> struct TypeInput<arr<T>> { template <class... ARGS> static void input(arr<T>& v, istream& is, int N, ARGS&&... args) { v.resize(N); REP(i, N) { TypeInput<T>::input(v[i], is, forward<ARGS>(args)...); } } }; template <class T> struct TypeInput<arr2<T>> { template <class... ARGS> static void input(arr2<T>& v, istream& is, int H, int W, ARGS&&... args) { v.init(W, H); REP(y, H) { REP(x, W) { TypeInput<T>::input(v(x, y), is, forward<ARGS>(args)...); } } } }; template <class... ARGS> struct InputParam { tuple<ARGS...> args_; InputParam(tuple<ARGS...>&& args) : args_(args) {} template <class T, class C = decltype(TypeInput<T>())> operator T() const { T v; apply([&](auto&&... args) { TypeInput<T>::input(v, mis, args...); }, args_); return v; } }; struct inputObject { template <class T, class C = decltype(TypeInput<T>())> operator T() { T v; TypeInput<T>::input(v, mis); return v; } template <class... T> InputParam<T...> operator()(T&&... args) { return InputParam<T...>(forward_as_tuple(args...)); } }; struct StdIO { OutputStream out; PrintStream prn; inputObject in; StdIO() : out(mos), prn(mos) { cout << fixed << setprecision(numeric_limits<double>::digits10); cerr << fixed << setprecision(numeric_limits<double>::digits10); } }; struct AlgoMain; #ifdef LOCAL_TEST #include <AlgoTest.h> #else struct Main { void Run(int argc, const char* argv[]) { (void)argc; (void)argv; InstanceRun<AlgoMain>(); } }; #endif constexpr int MOD = 1000000007; template <int M> struct modint { int raw; modint() { raw = 0; } modint(int v) { if (v < 0) { raw = (v % M) + M; } else if (v >= M) { raw = v % M; } else { raw = v; } } modint operator + (modint v) const { return modint(raw) += v; } modint operator - (modint v) const { return modint(raw) -= v; } modint operator * (modint v) const { return modint(raw) *= v; } modint& operator += (modint v) { raw += v.raw; if (raw >= M) { raw -= M; } return *this; } modint& operator -= (modint v) { raw -= v.raw; if (raw < 0) { raw += M; } return *this; } modint& operator *= (modint v) { raw = (raw * v.raw) % M; return *this; } modint pow(int n) const { return modint::pow(raw, n); } static modint pow(int a, int n) { if (n < 0) { abort(); } int r = 1; while (n) { if (n & 1) { r = (r * a) % M; } a = (a * a) % M; n >>= 1; } return modint(r); } modint inv() const { int a = raw; int b = M; int u = 1; int v = 0; while (b) { int t = a / b; a -= t * b; u -= t * v; swap(a, b); swap(u, v); } u %= M; if (u < 0) { u += M; } return u; } friend istream& operator>>(istream& is, modint& m) { int v; is >> v; m = modint(v); return is; } friend ostream& operator<<(ostream& os, modint const& m) { return os << m.raw; } }; using mint = modint<MOD>; using mints = arr<mint>; using mint2 = arr2<mint>; template <class T> class SegmentTree { private: vector<T> nodes_; std::function<T(T, T)> op_; T identity_; public: template <class OP> SegmentTree(int N, T identity, OP&& op) : nodes_(1LL << (msb(N - 1) + 2), identity) { identity_ = identity; op_ = op; } void Set(int i, T value) { i = nodes_.size() / 2 - 1 + i; nodes_[i] = value; while (i > 0) { i = (i - 1) / 2; nodes_[i] = op_(nodes_[2 * i + 1], nodes_[2 * i + 2]); } } T Get(int i) const { return nodes_[nodes_.size() / 2 - 1 + i]; } T Calc(int l, int r) const { return Calc(0, l, r, 0, nodes_.size() / 2); } private: T Calc(int i, int l, int r, int nl, int nr) const { if (l <= nl && nr <= r) { return nodes_[i]; } if (l >= nr || r <= nl) { return identity_; } int nc = (nl + nr) / 2; return op_(Calc(2 * i + 1, l, r, nl, nc), Calc(2 * i + 2, l, r, nc, nr)); } }; struct AlgoMain : public StdIO { void Run() { int N = in; int Q = in; string S = in; auto add = [&](int a, int b) { return a + b; }; SegmentTree<int> seg(N, 0, add); REP(i, N - 1) { if (S[i] == '(' && S[i + 1] == ')') { seg.Set(i, 1); } } REP(q, Q) { int op = in; if (op == 1) { int i = in(-1); if (S[i] == '(') { if (i + 1 < N && S[i + 1] == ')') { seg.Set(i, seg.Get(i) - 1); } if (i - 1 >= 0 && S[i - 1] == '(') { seg.Set(i - 1, seg.Get(i - 1) + 1); } S[i] = ')'; } else { if (i - 1 >= 0 && S[i - 1] == '(') { seg.Set(i - 1, seg.Get(i - 1) - 1); } if (i + 1 < N && S[i + 1] == ')') { seg.Set(i, seg.Get(i) + 1); } S[i] = '('; } } else { int l = in(-1); int r = in(-1); int ans = seg.Calc(l, r + 1); if (S[r] == '(' && r + 1 < N && S[r+1] == ')') { --ans; } out << ans; } } } };