Language: C++

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
#define ln '\n'
//const long long MOD = 1000000007LL;
const long long MOD = 998244353LL;
typedef long long ll;
typedef unsigned long long ull; 
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true;} return false; }
template<class T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true;} return false; }
///////////////////////////////////////////////////////////////////////////////////////////////////

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

using mint = modint<MOD>;

template<typename T>
struct LazySegmentTree {
    int N,h;
    vector<T> node,lazy;

    LazySegmentTree() = default;
    LazySegmentTree(vector<T> &v) {init(v);}

    void init(vector<T> &v) {
        int sz = v.size();
        N = 1; h = 0;
        while (N < sz) {
            N *= 2;
            h++;
        }
        node.assign(2*N,0); lazy.assign(2*N,0);
        for (int i = 0; i < sz; i++) node[i+N] = v[i];
        for (int i = N-1; i >= 1; i--) node[i] = node[i<<1|0] + node[i<<1|1];
    }

    void eval(int k) {
        if (lazy[k] != 0) {
            node[k] += lazy[k];
            if (k < N) {
                lazy[k<<1|0] += lazy[k]/2;
                lazy[k<<1|1] += lazy[k]/2;
            }
            lazy[k] = 0;
        }
    }

    void update(int l, int r, T val) { // [l,r) (0-indexed)
        l += N; r += N-1;
        for (int i = h; i > 0; i--) {
            eval(l>>i);
            eval(r>>i);
        }
        int a = l; int b = r++; T length = 1;
        while (l < r) {
            if (l & 1) lazy[l++] += length * val;
            if (r & 1) lazy[--r] += length * val;
            l >>= 1; r >>= 1; length <<= 1;
        }
        while (a >>= 1, b >>= 1, a) {
            if (lazy[a] == 0) {
                eval(a<<1|0); eval(a<<1|1);
                node[a] = node[a<<1|0] + node[a<<1|1];
            }
            if (lazy[b] == 0) {
                eval(b<<1|0); eval(b<<1|1);
                node[b] = node[b<<1|0] + node[b<<1|1];
            }
        }
    }

    T get(int l, int r) { // [l,r) (0-indexed)
        T res = 0;
        l += N; r += N-1;
        for (int i = h; i > 0; i--) {
            eval(l>>i); eval(r>>i);
        }
        r++;
        while (l < r) {
            if (l & 1) {
                eval(l);
                res += node[l++];
            }
            l >>= 1;
            if (r & 1) {
                eval(--r);
                res += node[r];
            }
            r >>= 1;
        }
        return res;
    }
};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    string S; cin >> S;

    mint ans = 1;
    rep(i,N) ans *= (i+1);
    ll R = 0, G = 0, B = 0, l = 0, val = 0;
    vector<mint> A(N);
    LazySegmentTree<mint> seg(A);
    int p = 0; int q = 0;
    rep(i,3*N) {
        if (S[i]=='R') {
            ++R;
            if (R > G && R > B) ++l;
            else if (R <= G && R <= B) {
                ans *= seg.get(p,q);
                ++p;
                seg.update(p,q,-1);
                --l;
            }
            else {
                seg.update(q,q+1,l);
                ++q;
            }
        } else if (S[i]=='G') {
            G++;
            if (G > B && G > R) ++l;
            else if (G <= B && G <= R) {
                ans *= seg.get(p,q);
                ++p;
                seg.update(p,q,-1);
                --l;
            }
            else {
                seg.update(q,q+1,l);
                ++q;
            }
        } else if (S[i]=='B') {
            B++;
            if (B > R && B > G) ++l;
            else if (B <= R && B <= G) {
                ans *= seg.get(p,q);
                ++p;
                seg.update(p,q,-1);
                --l;
            }
            else {
                seg.update(q,q+1,l);
                ++q;
            }
        }
    }

    cout << ans.a << ln;
}


Compiler output:
a.cc: In instantiation of 'void LazySegmentTree<T>::update(int, int, T) [with T = modint<998244353>]':
a.cc:167:27:   required from here
  167 |                 seg.update(p,q,-1);
      |                 ~~~~~~~~~~^~~~~~~~
a.cc:112:38: error: no match for 'operator<<=' (operand types are 'modint<998244353>' and 'int')
  112 |             l >>= 1; r >>= 1; length <<= 1;
      |                               ~~~~~~~^~~~~
In file included from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:41,
                 from a.cc:2:
/usr/include/c++/14/cstddef:157:5: note: candidate: 'template<class _IntegerType> constexpr std::__byte_op_t<_IntegerType>& std::operator<<=(byte&, _IntegerType)'
  157 |     operator<<=(byte& __b, _IntegerType __shift) noexcept
      |     ^~~~~~~~
/usr/include/c++/14/cstddef:157:5: note:   template argument deduction/substitution failed:
a.cc:112:31: note:   cannot convert 'length' (type 'modint<998244353>') to type 'std::byte&'
  112 |             l >>= 1; r >>= 1; length <<= 1;
      |                               ^~~~~~
a.cc:115:25: error: no match for 'operator==' (operand types are '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} and 'int')
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
In file included from /usr/include/c++/14/regex:68,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:181:
/usr/include/c++/14/bits/regex.h:1103:5: note: candidate: 'template<class _BiIter> bool std::__cxx11::operator==(const sub_match<_BiIter>&, const sub_match<_BiIter>&)'
 1103 |     operator==(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1103:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/regex.h:1199:5: note: candidate: 'template<class _Bi_iter, class _Ch_traits, class _Ch_alloc> bool std::__cxx11::operator==(__sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>&, const sub_match<_BiIter>&)'
 1199 |     operator==(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1199:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'std::__cxx11::__sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/regex.h:1274:5: note: candidate: 'template<class _Bi_iter, class _Ch_traits, class _Ch_alloc> bool std::__cxx11::operator==(const sub_match<_BiIter>&, __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>&)'
 1274 |     operator==(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1274:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/regex.h:1366:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator==(const typename std::iterator_traits<_Iter>::value_type*, const sub_match<_BiIter>&)'
 1366 |     operator==(typename iterator_traits<_Bi_iter>::value_type const* __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1366:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   mismatched types 'const std::__cxx11::sub_match<_BiIter>' and 'int'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/regex.h:1441:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator==(const sub_match<_BiIter>&, const typename std::iterator_traits<_Iter>::value_type*)'
 1441 |     operator==(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1441:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/regex.h:1534:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator==(const typename std::iterator_traits<_Iter>::value_type&, const sub_match<_BiIter>&)'
 1534 |     operator==(typename iterator_traits<_Bi_iter>::value_type const& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1534:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   mismatched types 'const std::__cxx11::sub_match<_BiIter>' and 'int'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/regex.h:1613:5: note: candidate: 'template<class _Bi_iter> bool std::__cxx11::operator==(const sub_match<_BiIter>&, const typename std::iterator_traits<_Iter>::value_type&)'
 1613 |     operator==(const sub_match<_Bi_iter>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:1613:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::__cxx11::sub_match<_BiIter>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/regex.h:2186:5: note: candidate: 'template<class _Bi_iter, class _Alloc> bool std::__cxx11::operator==(const match_results<_BiIter, _Alloc>&, const match_results<_BiIter, _Alloc>&)'
 2186 |     operator==(const match_results<_Bi_iter, _Alloc>& __m1,
      |     ^~~~~~~~
/usr/include/c++/14/bits/regex.h:2186:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::__cxx11::match_results<_BiIter, _Alloc>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
In file included from /usr/include/c++/14/bits/stl_algobase.h:64,
                 from /usr/include/c++/14/algorithm:60,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:51:
/usr/include/c++/14/bits/stl_pair.h:1033:5: note: candidate: 'template<class _T1, class _T2> constexpr bool std::operator==(const pair<_T1, _T2>&, const pair<_T1, _T2>&)'
 1033 |     operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_pair.h:1033:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::pair<_T1, _T2>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
In file included from /usr/include/c++/14/bits/stl_algobase.h:67:
/usr/include/c++/14/bits/stl_iterator.h:441:5: note: candidate: 'template<class _Iterator> constexpr bool std::operator==(const reverse_iterator<_Iterator>&, const reverse_iterator<_Iterator>&)'
  441 |     operator==(const reverse_iterator<_Iterator>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:441:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::reverse_iterator<_Iterator>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/stl_iterator.h:486:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr bool std::operator==(const reverse_iterator<_Iterator>&, const reverse_iterator<_IteratorR>&)'
  486 |     operator==(const reverse_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:486:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::reverse_iterator<_Iterator>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/stl_iterator.h:1667:5: note: candidate: 'template<class _IteratorL, class _IteratorR> constexpr bool std::operator==(const move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)'
 1667 |     operator==(const move_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1667:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::move_iterator<_IteratorL>'
  115 |             if (lazy[a] == 0) {
      |                 ~~~~~~~~^~~~
/usr/include/c++/14/bits/stl_iterator.h:1737:5: note: candidate: 'template<class _Iterator> constexpr bool std::operator==(const move_iterator<_IteratorL>&, const move_iterator<_IteratorL>&)'
 1737 |     operator==(const move_iterator<_Iterator>& __x,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1737:5: note:   template argument deduction/substitution failed:
a.cc:115:25: note:   '__gnu_cxx::__alloc_traits<std::allocator<modint<998244353> >, modint<998244353> >::value_type' {aka 'modint<998244353>'} is not derived from 'const std::move_iterator<_IteratorL>'
  115 |             if (lazy[a] == 0)