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

#include <bits/stdc++.h>
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;

#pragma GCC optimize("O3")
#ifdef LOCAL
#include "/Users/lbjlc/Desktop/coding/debug_utils.h"
#else
#define print(...) ;
#define printn(...) ;
#define fprint(...) ;
#define fprintn(...) ;
#endif

#define rep(i, a, b) for (auto i = (a); i < (b); i++)
#define rrep(i, a, b) for (auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define pb push_back
// #define mp make_pair
#define fi first
#define se second
#define maxi(x, y) x = max(x, y)
#define mini(x, y) x = min(x, y)
// long long fact(long long n) { if(!n) return 1; return n*fact(n-1); }
// #define endl '\\n'
#define solve_testcase                                                         \\
  int T;                                                                       \\
  cin >> T;                                                                    \\
  for (int t = 1; t <= T; t++) {                                               \\
    solve(t);                                                                  \\
  }

// long long gcd(long long x, long long y) { return y ? gcd(y, x % y) : x; }

typedef unsigned long long ull;
typedef long long ll;

typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pdd> vpdd;
typedef vector<long long> vll;
#define bd(type, op, val) bind(op<type>(), std::placeholders::_1, val)

const int MAXN = 1e6 + 10;

void solve(int tt) {
  // cout<<"Case #"<<tt<<": ";
}

string to_ter(int x, int k = -1) {
  string res;
  while (x) {
    res += '0' + x % 3;
    x /= 3;
  }
  if (k >= 0) {
    while (res.size() < k)
      res += '0';
  }
  return res;
}
int to_int(const string &s) {
  int res = 0;
  // rrep(i,s.size()-1,-1)
  //     res=res*3+(s[i]-'0');
  for (int i = s.size() - 1; i >= 0; i--)
    res = res * 3 + (s[i] - '0');
  // print(s,res);
  return res;
}
bool add(string &x, const string &y) {
  int n1 = x.size(), n2 = y.size(), carry = 0;
  rep(i, 0, n1) {
    if (i < n1)
      carry += x[i] - '0';
    if (i < n2)
      carry += y[i] - '0';
    x[i] = carry % 3 + '0';
    carry /= 3;
  }
  return carry == 0;
}

vi cal_inst(string &s) {
  int n = s.size();
  vi res(1);
  int i = 0;
  while (i < n) {
    if (s[i] == 'R') {
      res.back()++;
      i++;
    } else {
      int j = i;
      for (; j < n && s[j] == 'S'; j++)
        ;
      if ((j - i) % 2)
        res.pb(0);
      i = j;
    }
  }
  if (s.back() == 'S')
    res.pop_back();
  return res;
}

char rev(char c) {
  if (c > '0')
    return '0' + (3 - (c - '0'));
  return c;
}
string rev(string s) {
  for (auto &c : s)
    c = rev(c);
  return s;
}

int len(string &s) {
  int res = s.size() - 1;
  while (res >= 0 && s[res] == '0')
    res--;
  return res + 1;
}

int power[13] = {};
int revmap[MAXN] = {};
int tmpres[MAXN];
int rev(int x) {
  for (int flag = 1; flag < power[12]; flag *= 3) {
    int tmp = x / flag % 3;
    if (tmp == 1)
      x += flag;
    else if (tmp == 2)
      x -= flag;
  }
  return x;
}

void cal(vi inst, int n, int tot) {
  // vi tmpres(tot,-1);
  fill(tmpres, tmpres + tot, -1);

  rep(i, 0, tot) {
    if (tmpres[i] >= 0)
      continue;

    int cur = i, ok = 1;
    for (auto x : inst) {
      cur += x;
      if (cur >= power[n]) {
        ok = 0;
        cur %= power[n];
      }
      cur = revmap[cur];
    }
    // if(i<=9) print(i,cur);
    tmpres[i] = cur;
    // assert(cur>=0);
    if (!ok)
      continue;
    int flag = 1, tmp;
    for (; flag <= i || flag <= cur; flag *= 3)
      ;

    if (inst.size() % 2 == 0) {
      for (tmp = flag; tmp < power[n]; tmp += flag) {
        tmpres[tmp + i] = tmp + cur;
      }
    } else {
      for (tmp = flag; tmp < power[n]; tmp += flag) {
        tmpres[tmp + i] = revmap[tmp] + cur;
      }
    }
  }
  // print(1);
  // print(*max_element(all(res)),*min_element(all(res)));
  // return res;
}

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  // solve_testcase;

  int n;
  string s;
  cin >> n;
  cin >> s;

  // n=12;
  // rep(i,0,1e5) s+="RS";

  power[0] = 1;
  rep(i, 1, 13) power[i] = power[i - 1] * 3;

  int tot = 1;
  rep(i, 0, n) tot *= 3;

  rep(i, 0, tot) {
    if (i >= 3) {
      if (i % 3 == 0)
        revmap[i] = revmap[i / 3] * 3;
      else
        revmap[i] = revmap[i - i % 3] + rev(i % 3);
    } else
      revmap[i] = rev(i);
  }
  // printn(revmap,9);

  vi inst = cal_inst(s);
  for (auto &x : inst)
    x %= tot;

  // print(inst);

  int i = 0;
  int bound = 500;
  vi res(tot);
  iota(all(res), 0);
  while (i < inst.size()) {
    int cur = inst[i];
    vi cur_inst({cur});
    for (++i; i < inst.size() && cur + inst[i] < bound; i++) {
      cur += inst[i];
      cur_inst.pb(inst[i]);
    }
    cal(cur_inst, n, tot);
    // print(tmp);
    rep(j, 0, tot) res[j] = tmpres[res[j]];
    // print(cur_inst,tmp);
    // print(res);
    // sort(all(tmp)); print(tmp);
  }
  if (s.back() == 'R') {
    rep(i, 0, tot) { res[i] = revmap[res[i]]; }
  }
  for (auto x : res)
    cout << x << ' ';
  cout << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;

#pragma GCC optimize("O3")
#ifdef LOCAL
#include "/Users/lbjlc/Desktop/coding/debug_utils.h"
#else
#define print(...) ;
#define printn(...) ;
#define fprint(...) ;
#define fprintn(...) ;
#endif

#define rep(i, a, b) for (auto i = (a); i < (b); i++)
#define rrep(i, a, b) for (auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define pb push_back
// #define mp make_pair
#define fi first
#define se second
#define maxi(x, y) x = max(x, y)
#define mini(x, y) x = min(x, y)
// long long fact(long long n) { if(!n) return 1; return n*fact(n-1); }
// #define endl '\\n'
#define solve_testcase                                                         \\
  int T;                                                                       \\
  cin >> T;                                                                    \\
  for (int t = 1; t <= T; t++) {                                               \\
    solve(t);                                                                  \\
  }

// long long gcd(long long x, long long y) { return y ? gcd(y, x % y) : x; }

typedef unsigned long long ull;
typedef long long ll;

typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pdd> vpdd;
typedef vector<long long> vll;
#define bd(type, op, val) bind(op<type>(), std::placeholders::_1, val)

const int MAXN = 1e6 + 10;

void solve(int tt) {
  // cout<<"Case #"<<tt<<": ";
}

string to_ter(int x, int k = -1) {
  string res;
  while (x) {
    res += '0' + x % 3;
    x /= 3;
  }
  if (k >= 0) {
    while (res.size() < k)
      res += '0';
  }
  return res;
}
int to_int(const string &s) {
  int res = 0;
  // rrep(i,s.size()-1,-1)
  //     res=res*3+(s[i]-'0');
  for (int i = s.size() - 1; i >= 0; i--)
    res = res * 3 + (s[i] - '0');
  // print(s,res);
  return res;
}
bool add(string &x, const string &y) {
  int n1 = x.size(), n2 = y.size(), carry = 0;
  rep(i, 0, n1) {
    if (i < n1)
      carry += x[i] - '0';
    if (i < n2)
      carry += y[i] - '0';
    x[i] = carry % 3 + '0';
    carry /= 3;
  }
  return carry == 0;
}

vi cal_inst(string &s) {
  int n = s.size();
  vi res(1);
  int i = 0;
  while (i < n) {
    if (s[i] == 'R') {
      res.back()++;
      i++;
    } else {
      int j = i;
      for (; j < n && s[j] == 'S'; j++)
        ;
      if ((j - i) % 2)
        res.pb(0);
      i = j;
    }
  }
  if (s.back() == 'S')
    res.pop_back();
  return res;
}

char rev(char c) {
  if (c > '0')
    return '0' + (3 - (c - '0'));
  return c;
}
string rev(string s) {
  for (auto &c : s)
    c = rev(c);
  return s;
}

int len(string &s) {
  int res = s.size() - 1;
  while (res >= 0 && s[res] == '0')
    res--;
  return res + 1;
}

int power[13] = {};
int revmap[MAXN] = {};
int tmpres[MAXN];
int rev(int x) {
  for (int flag = 1; flag < power[12]; flag *= 3) {
    int tmp = x / flag % 3;
    if (tmp == 1)
      x += flag;
    else if (tmp == 2)
      x -= flag;
  }
  return x;
}

void cal(vi inst, int n, int tot) {
  // vi tmpres(tot,-1);
  fill(tmpres, tmpres + tot, -1);

  rep(i, 0, tot) {
    if (tmpres[i] >= 0)
      continue;

    int cur = i, ok = 1;
    for (auto x : inst) {
      cur += x;
      if (cur >= power[n]) {
        ok = 0;
        cur %= power[n];
      }
      cur = revmap[cur];
    }
    // if(i<=9) print(i,cur);
    tmpres[i] = cur;
    // assert(cur>=0);
    if (!ok)
      continue;
    int flag = 1, tmp;
    for (; flag <= i || flag <= cur; flag *= 3)
      ;

    if (inst.size() % 2 == 0) {
      for (tmp = flag; tmp < power[n]; tmp += flag) {
        tmpres[tmp + i] = tmp + cur;
      }
    } else {
      for (tmp = flag; tmp < power[n]; tmp += flag) {
        tmpres[tmp + i] = revmap[tmp] + cur;
      }
    }
  }
  // print(1);
  // print(*max_element(all(res)),*min_element(all(res)));
  // return res;
}

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  // solve_testcase;

  int n;
  string s;
  cin >> n;
  cin >> s;

  // n=12;
  // rep(i,0,1e5) s+="RS";

  power[0] = 1;
  rep(i, 1, 13) power[i] = power[i - 1] * 3;

  int tot = 1;
  rep(i, 0, n) tot *= 3;

  rep(i, 0, tot) {
    if (i >= 3) {
      if (i % 3 == 0)
        revmap[i] = revmap[i / 3] * 3;
      else
        revmap[i] = revmap[i - i % 3] + rev(i % 3);
    } else
      revmap[i] = rev(i);
  }
  // printn(revmap,9);

  vi inst = cal_inst(s);
  for (auto &x : inst)
    x %= tot;

  // print(inst);

  int i = 0;
  int bound = 81;
  vi res(tot);
  iota(all(res), 0);
  while (i < inst.size()) {
    int cur = inst[i];
    vi cur_inst({cur});
    for (++i; i < inst.size() && cur + inst[i] < bound; i++) {
      cur += inst[i];
      cur_inst.pb(inst[i]);
    }
    cal(cur_inst, n, tot);
    // print(tmp);
    rep(j, 0, tot) res[j] = tmpres[res[j]];
    // print(cur_inst,tmp);
    // print(res);
    // sort(all(tmp)); print(tmp);
  }
  if (s.back() == 'R') {
    rep(i, 0, tot) { res[i] = revmap[res[i]]; }
  }
  for (auto x : res)
    cout << x << ' ';
  cout << endl;

  return 0;
}