Problem p02671 (C++) — buggy submission, verdict: Time Limit Exceeded

#define ENABLE_DEBUG 0
// Kana's kitchen {{{
#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define LOOP(k)                                                                \\
  for (i64 ngtkana_is_a_genius = 0; ngtkana_is_a_genius < (i64)k;              \\
       ngtkana_is_a_genius++)

using i32 = std::int_least32_t;
using i64 = std::int_least64_t;
using u32 = std::uint_least32_t;
using u64 = std::uint_least64_t;
using usize = std::size_t;

template <class T> using vec = std::vector<T>;
template <class T> using numr = std::numeric_limits<T>;

#ifdef NGTKANA
#include <debug.hpp>
#else
#define DEBUG(...) (void)0
#endif
/*}}}*/
// mint{{{
template <class ModType> struct modint {
  using value_type = typename ModType::value_type;
  using mint = modint<ModType>;
  using mod_type = ModType;

  static value_type mod() { return ModType::value; }

private:
  static value_type inverse(value_type x) {
    value_type y = 1, u = mod(), v = 0;
    while (x) {
      value_type q = u / x;
      u -= q * x;
      std::swap(x, u);
      v -= q * y;
      std::swap(y, v);
    }
    assert(x == 0 && std::abs(y) == mod() && std::abs(u) == 1 &&
           std::abs(v) < mod());
    return v < 0 ? v + mod() : v;
  }

public:
  // the member variable
  value_type value;

  // constructors
  modint() = default;
  modint(modint const &) = default;
  modint(modint &&) = default;
  modint &operator=(modint const &) = default;
  modint &operator=(modint &&) = default;
  ~modint() = default;

  template <class T>
  modint(T t)
      : value([t]() mutable {
          if (t <= -static_cast<T>(mod()) || static_cast<T>(mod()) <= t)
            t %= mod();
          return t < 0 ? t + mod() : t;
        }()) {}

  // operators
  mint &operator+=(mint y) {
    value += y.value;
    if (mod() <= value)
      value -= mod();
    return *this;
  }

  mint &operator-=(mint y) {
    value -= y.value;
    if (value < 0)
      value += mod();
    return *this;
  }

  mint &operator*=(mint y) {
    value = (long long)value * y.value % mod();
    return *this;
  }

  mint &operator/=(mint y) {
    value = (long long)value * inverse(y.value) % mod();
    return *this;
  }

  mint &operator++() { return *this += 1; }
  mint &operator--() { return *this -= 1; }
  mint operator++(int) {
    mint this_ = *this;
    ++*this;
    return this_;
  }
  mint operator--(int) {
    mint this_ = *this;
    --*this;
    return this_;
  }

  // static member functions
  static mint inv(mint x) { return inverse(x.value); }

  static mint m1pow(long long y) { return y % 2 ? -1 : 1; }

  static mint pow(mint x, unsigned long long y) {
    mint ans = 1;
    for (; y; y >>= 1) {
      if (y & 1ull)
        ans *= x;
      x *= x;
    }
    return ans;
  }

  // non-member functions
  mint &add_assign(mint y) { return *this += y; }
  mint &sub_assign(mint y) { return *this -= y; }
  mint &mul_assign(mint y) { return *this *= y; }
  mint &div_assign(mint y) { return *this /= y; }
  mint &inv_assign() { return *this = inv(*this); }
  mint &pow_assign(unsigned long long y) { return *this = pow(*this, y); }

  mint add(mint y) {
    mint ans = *this;
    return ans.add_assign(y);
  }
  mint sub(mint y) {
    mint ans = *this;
    return ans.sub_assign(y);
  }
  mint mul(mint y) {
    mint ans = *this;
    return ans.mul_assign(y);
  }
  mint div(mint y) {
    mint ans = *this;
    return ans.div_assign(y);
  }
  mint inv() {
    mint ans = *this;
    return ans.inv_assign();
  }
  mint pow(unsigned long long y) { return pow(*this, y); }

  template <class F> mint map(F const &f) {
    value = f(value);
    return *this;
  }
};

template <class T> std::istream &operator>>(std::istream &is, modint<T> &x) {
  typename modint<T>::value_type y;
  is >> y;
  x = modint<T>{y};
  return is;
}
template <class T> std::ostream &operator<<(std::ostream &os, modint<T> x) {
  return os << x.value;
}

template <class T> modint<T> operator+(modint<T> x, modint<T> y) {
  return x += y;
}
template <class T> modint<T> operator-(modint<T> x, modint<T> y) {
  return x -= y;
}
template <class T> modint<T> operator*(modint<T> x, modint<T> y) {
  return x *= y;
}
template <class T> modint<T> operator/(modint<T> x, modint<T> y) {
  return x /= y;
}
template <class T> bool operator==(modint<T> x, modint<T> y) {
  return x.value == y.value;
}
template <class T> bool operator!=(modint<T> x, modint<T> y) {
  return x.value != y.value;
}

template <class T, class U> modint<T> operator+(modint<T> x, U y) {
  return x + modint<T>(y);
}
template <class T, class U> modint<T> operator-(modint<T> x, U y) {
  return x - modint<T>(y);
}
template <class T, class U> modint<T> operator*(modint<T> x, U y) {
  return x * modint<T>(y);
}
template <class T, class U> modint<T> operator/(modint<T> x, U y) {
  return x / modint<T>(y);
}
template <class T, class U> bool operator==(modint<T> x, U y) {
  return x == modint<T>(y);
}
template <class T, class U> bool operator!=(modint<T> x, U y) {
  return x != modint<T>(y);
}

template <class T, class U> modint<T> operator+(U x, modint<T> y) {
  return modint<T>(x) + y;
}
template <class T, class U> modint<T> operator-(U x, modint<T> y) {
  return modint<T>(x) - y;
}
template <class T, class U> modint<T> operator*(U x, modint<T> y) {
  return modint<T>(x) * y;
}
template <class T, class U> modint<T> operator/(U x, modint<T> y) {
  return modint<T>(x) / y;
}
template <class T, class U> bool operator==(U x, modint<T> y) {
  return modint<T>(x) == y;
}
template <class T, class U> bool operator!=(U x, modint<T> y) {
  return modint<T>(x) != y;
}
/*}}}*/
using mint = modint<std::integral_constant<i32, 3>>;

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
  std::cout << std::setprecision(15) << std::fixed;

  usize n;
  std::cin >> n;
  vec<usize> tpow(n + 1, 1);
  for (usize i = 0; i < n; i++) {
    tpow.at(i + 1) = tpow.at(i) * 3;
  }
  usize N = tpow.back();
  DEBUG(n, N, tpow);

  bool has_s = false;
  vec<vec<mint>> sigma(n);
  for (usize i = 0; i < n; i++) {
    sigma.at(i).resize(tpow.at(i));
  }
  DEBUG(matrix_style(sigma));

  // apply-s{{{
  auto apply_s = [&](usize a) {
    for (usize k = 0; k < n; k++) {
      usize K = tpow.at(k);
      usize r = a % (3 * K);
      if (K <= r && r < 2 * K) {
        a += K;
      } else if (2 * K <= r) {
        a -= K;
      }
    }
    return a;
  };
  /*}}}*/
  // mul_r_from_the_left{{{
  auto mul_r_from_the_left = [&] {
    for (usize i = n - 1; i != -1; i--) {
      usize I = tpow.at(i);
      usize j = I - 1;
      if (has_s) {
        j = apply_s(j);
      }
      DEBUG(i, j);
      for (usize k = 0; k < i; k++) {
        usize K = tpow.at(k);
        usize r = j % (3 * K);
        usize val = sigma.at(k).at(r % K).value;
        DEBUG(j, val);
        j -= val * K;
        if (r < val * K)
          j += 3 * K;
        DEBUG(j, val);
      }
      if (has_s) {
        sigma.at(i).at(j)--;
      } else {
        sigma.at(i).at(j)++;
      }
    }
  };
  /*}}}*/
  // get-ans{{{
  auto get_ans = [&] {
    vec<usize> ans(N);
    std::iota(ALL(ans), 0u);
    for (usize j = 0; j < N; j++) {
      usize &a = ans.at(j);
      for (usize k = n - 1; k != -1; k--) {
        usize K = tpow.at(k);
        usize r = a % (3 * K);
        usize val = sigma.at(k).at(r % K).value;
        a += val * K;
        if ((3 - val) * K <= r)
          a -= 3 * K;
      }
      if (has_s) {
        a = apply_s(a);
      }
    }
    return ans;
  };
  /*}}}*/
  DEBUG(get_ans());

  std::string s;
  std::cin >> s;
  for (char c : s) {
    DEBUG(c);
    if (c == 'S') {
      has_s ^= 1;
    }
    if (c == 'R') {
      mul_r_from_the_left();
    }
    DEBUG(has_s);
    DEBUG(matrix_style(sigma));
    DEBUG();
  }

  auto ans = get_ans();
  for (usize i = 0; i < N; i++) {
    std::cout << (i ? " " : "") << ans.at(i);
  }
  std::cout << '\\n';
}


Error: TLE

Fixed submission:

#define ENABLE_DEBUG 0
// Kana's kitchen {{{
#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define LOOP(k)                                                                \\
  for (i64 ngtkana_is_a_genius = 0; ngtkana_is_a_genius < (i64)k;              \\
       ngtkana_is_a_genius++)

using i32 = std::int_least32_t;
using i64 = std::int_least64_t;
using u32 = std::uint_least32_t;
using u64 = std::uint_least64_t;
using usize = std::size_t;

template <class T> using vec = std::vector<T>;
template <class T> using numr = std::numeric_limits<T>;

#ifdef NGTKANA
#include <debug.hpp>
#else
#define DEBUG(...) (void)0
#endif
/*}}}*/
// mint{{{
template <class ModType> struct modint {
  using value_type = typename ModType::value_type;
  using mint = modint<ModType>;
  using mod_type = ModType;

  static value_type mod() { return ModType::value; }

private:
  static value_type inverse(value_type x) {
    value_type y = 1, u = mod(), v = 0;
    while (x) {
      value_type q = u / x;
      u -= q * x;
      std::swap(x, u);
      v -= q * y;
      std::swap(y, v);
    }
    assert(x == 0 && std::abs(y) == mod() && std::abs(u) == 1 &&
           std::abs(v) < mod());
    return v < 0 ? v + mod() : v;
  }

public:
  // the member variable
  value_type value;

  // constructors
  modint() = default;
  modint(modint const &) = default;
  modint(modint &&) = default;
  modint &operator=(modint const &) = default;
  modint &operator=(modint &&) = default;
  ~modint() = default;

  template <class T>
  modint(T t)
      : value([t]() mutable {
          if (t <= -static_cast<T>(mod()) || static_cast<T>(mod()) <= t)
            t %= mod();
          return t < 0 ? t + mod() : t;
        }()) {}

  // operators
  mint &operator+=(mint y) {
    value += y.value;
    if (mod() <= value)
      value -= mod();
    return *this;
  }

  mint &operator-=(mint y) {
    value -= y.value;
    if (value < 0)
      value += mod();
    return *this;
  }

  mint &operator*=(mint y) {
    value = (long long)value * y.value % mod();
    return *this;
  }

  mint &operator/=(mint y) {
    value = (long long)value * inverse(y.value) % mod();
    return *this;
  }

  mint &operator++() { return *this += 1; }
  mint &operator--() { return *this -= 1; }
  mint operator++(int) {
    mint this_ = *this;
    ++*this;
    return this_;
  }
  mint operator--(int) {
    mint this_ = *this;
    --*this;
    return this_;
  }

  // static member functions
  static mint inv(mint x) { return inverse(x.value); }

  static mint m1pow(long long y) { return y % 2 ? -1 : 1; }

  static mint pow(mint x, unsigned long long y) {
    mint ans = 1;
    for (; y; y >>= 1) {
      if (y & 1ull)
        ans *= x;
      x *= x;
    }
    return ans;
  }

  // non-member functions
  mint &add_assign(mint y) { return *this += y; }
  mint &sub_assign(mint y) { return *this -= y; }
  mint &mul_assign(mint y) { return *this *= y; }
  mint &div_assign(mint y) { return *this /= y; }
  mint &inv_assign() { return *this = inv(*this); }
  mint &pow_assign(unsigned long long y) { return *this = pow(*this, y); }

  mint add(mint y) {
    mint ans = *this;
    return ans.add_assign(y);
  }
  mint sub(mint y) {
    mint ans = *this;
    return ans.sub_assign(y);
  }
  mint mul(mint y) {
    mint ans = *this;
    return ans.mul_assign(y);
  }
  mint div(mint y) {
    mint ans = *this;
    return ans.div_assign(y);
  }
  mint inv() {
    mint ans = *this;
    return ans.inv_assign();
  }
  mint pow(unsigned long long y) { return pow(*this, y); }

  template <class F> mint map(F const &f) {
    value = f(value);
    return *this;
  }
};

template <class T> std::istream &operator>>(std::istream &is, modint<T> &x) {
  typename modint<T>::value_type y;
  is >> y;
  x = modint<T>{y};
  return is;
}
template <class T> std::ostream &operator<<(std::ostream &os, modint<T> x) {
  return os << x.value;
}

template <class T> modint<T> operator+(modint<T> x, modint<T> y) {
  return x += y;
}
template <class T> modint<T> operator-(modint<T> x, modint<T> y) {
  return x -= y;
}
template <class T> modint<T> operator*(modint<T> x, modint<T> y) {
  return x *= y;
}
template <class T> modint<T> operator/(modint<T> x, modint<T> y) {
  return x /= y;
}
template <class T> bool operator==(modint<T> x, modint<T> y) {
  return x.value == y.value;
}
template <class T> bool operator!=(modint<T> x, modint<T> y) {
  return x.value != y.value;
}

template <class T, class U> modint<T> operator+(modint<T> x, U y) {
  return x + modint<T>(y);
}
template <class T, class U> modint<T> operator-(modint<T> x, U y) {
  return x - modint<T>(y);
}
template <class T, class U> modint<T> operator*(modint<T> x, U y) {
  return x * modint<T>(y);
}
template <class T, class U> modint<T> operator/(modint<T> x, U y) {
  return x / modint<T>(y);
}
template <class T, class U> bool operator==(modint<T> x, U y) {
  return x == modint<T>(y);
}
template <class T, class U> bool operator!=(modint<T> x, U y) {
  return x != modint<T>(y);
}

template <class T, class U> modint<T> operator+(U x, modint<T> y) {
  return modint<T>(x) + y;
}
template <class T, class U> modint<T> operator-(U x, modint<T> y) {
  return modint<T>(x) - y;
}
template <class T, class U> modint<T> operator*(U x, modint<T> y) {
  return modint<T>(x) * y;
}
template <class T, class U> modint<T> operator/(U x, modint<T> y) {
  return modint<T>(x) / y;
}
template <class T, class U> bool operator==(U x, modint<T> y) {
  return modint<T>(x) == y;
}
template <class T, class U> bool operator!=(U x, modint<T> y) {
  return modint<T>(x) != y;
}
/*}}}*/
using mint = modint<std::integral_constant<i32, 3>>;

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
  std::cout << std::setprecision(15) << std::fixed;

  usize n;
  std::cin >> n;
  vec<usize> tpow(n + 1, 1);
  for (usize i = 0; i < n; i++) {
    tpow.at(i + 1) = tpow.at(i) * 3;
  }
  usize N = tpow.back();
  DEBUG(n, N, tpow);

  bool has_s = false;
  vec<vec<mint>> sigma(n);
  for (usize i = 0; i < n; i++) {
    sigma.at(i).resize(tpow.at(i));
  }
  DEBUG(matrix_style(sigma));

  // apply-s{{{
  auto apply_s = [&](usize a) {
    for (usize k = 0; k < n; k++) {
      usize K = tpow.at(k);
      usize r = a % (3 * K);
      if (K <= r && r < 2 * K) {
        a += K;
      } else if (2 * K <= r) {
        a -= K;
      }
    }
    return a;
  };
  /*}}}*/
  // mul_r_from_the_left{{{
  auto mul_r_from_the_left = [&] {
    for (usize i = n - 1; i != -1; i--) {
      usize I = tpow.at(i);
      usize j = I - 1;
      if (has_s) {
        j = apply_s(j);
      }
      DEBUG(i, j);
      for (usize k = 0; k < i; k++) {
        usize K = tpow.at(k);
        usize r = j % (3 * K);
        usize val = sigma.at(k).at(r % K).value;
        DEBUG(j, val);
        j -= val * K;
        if (r < val * K)
          j += 3 * K;
        DEBUG(j, val);
      }
      if (has_s) {
        sigma.at(i).at(j)--;
      } else {
        sigma.at(i).at(j)++;
      }
    }
  };
  /*}}}*/
  // get-ans{{{
  auto get_ans = [&] {
    vec<usize> ans(N);
    std::iota(ALL(ans), 0u);
    for (usize j = 0; j < N; j++) {
      usize &a = ans.at(j);
      for (usize k = n - 1; k != -1; k--) {
        usize K = tpow.at(k);
        usize r = a % (3 * K);
        usize val = sigma.at(k).at(r % K).value;
        a += val * K;
        if ((3 - val) * K <= r)
          a -= 3 * K;
      }
      if (has_s) {
        a = apply_s(a);
      }
    }
    return ans;
  };
  /*}}}*/
  DEBUG(get_ans());

  std::string s;
  std::cin >> s;
  for (char c : s) {
    DEBUG(c);
    if (c == 'S') {
      has_s ^= 1;
    }
    if (c == 'R') {
      mul_r_from_the_left();
    }
    DEBUG(has_s);
    DEBUG(matrix_style(sigma));
    auto ans = get_ans();
    DEBUG(ans);
    DEBUG();
  }

  auto ans = get_ans();
  for (usize i = 0; i < N; i++) {
    std::cout << (i ? " " : "") << ans.at(i);
  }
  std::cout << '\\n';
}