Problem p02943 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin >>
#define Z class
#define ll long long
#define ln cout << '\n'
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n", a)
#define mem(a) memset(a, 0, sizeof(a))
#define all(c) (c).begin(), (c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i, n) for (ll i = (ll)(n)-1; i >= 0; i--)
#define REP(i, m, n) for (ll i = (ll)(m); i < (ll)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define tr(it, c) for (iter(c) it = (c).begin(); it != (c).end(); it++)
template <Z A> void pr(A a) {
  cout << a;
  ln;
}
template <Z A, Z B> void pr(A a, B b) {
  cout << a << ' ';
  pr(b);
}
template <Z A, Z B, Z C> void pr(A a, B b, C c) {
  cout << a << ' ';
  pr(b, c);
}
template <Z A, Z B, Z C, Z D> void pr(A a, B b, C c, D d) {
  cout << a << ' ';
  pr(b, c, d);
}
template <Z A> void PR(A a, ll n) {
  rep(i, n) {
    if (i)
      cout << ' ';
    cout << a[i];
  }
  ln;
}
ll check(ll n, ll m, ll x, ll y) { return x >= 0 && x < n && y >= 0 && y < m; }
const ll MAX = 1e9 + 7, MAXL = 1LL << 61, dx[4] = {-1, 0, 1, 0},
         dy[4] = {0, 1, 0, -1};
typedef pair<ll, ll> P;

void sa_is_countingAlphabets(const int *s, int n, int size, vector<int> &b,
                             bool f = false) {
  if (f || (int)b.size() / 2 >= size) {
    vector<int>::iterator a = f ? b.begin() : b.begin() + size;
    fill(a, a + size, 0);
    for (int i = 0; i < n; i++)
      a[(int)s[i]]++;
  }
}

void sa_is_getBucketOffsets(const int *s, int n, bool dir, int size,
                            vector<int> &b) {
  vector<int>::iterator a;
  if ((int)b.size() / 2 < size) {
    sa_is_countingAlphabets(s, n, size, b, true);
    a = b.begin();
  } else
    a = b.begin() + size;
  int cumsum = 1;
  if (dir) {
    for (int i = 0; i < size; i++) {
      cumsum += a[i];
      b[i] = cumsum;
    }
  } else {
    for (int i = 0; i < size; i++) {
      int x = a[i];
      b[i] = cumsum;
      cumsum += x;
    }
  }
}

void sa_is_inducedSort(const int *s, int n, int size, const vector<bool> &types,
                       int *sa, vector<int> &b) {
  sa_is_getBucketOffsets(s, n, false, size, b);
  for (int i = 0; i < n; i++) {
    int j = sa[i] - 1;
    if (j >= 0 && !types[j])
      sa[b[(int)s[j]]++] = j;
  }
  sa_is_getBucketOffsets(s, n, true, size, b);
  for (int i = n; i >= 1; i--) {
    int j = sa[i] - 1;
    if (j >= 0 && types[j])
      sa[--b[(int)s[j]]] = j;
  }
}

void sa_is_rec(const int *s, int n, int size, int *sa, vector<int> &b) {
  vector<bool> types(n + 1);
  types[n - 1] = 0;
  types[n] = 1;
  for (int i = n - 2; i >= 0; i--)
    types[i] = s[i] < s[i + 1] || (s[i] == s[i + 1] && types[i + 1]);
  sa_is_countingAlphabets(s, n, size, b);
  sa_is_getBucketOffsets(s, n, true, size, b);
  fill(sa, sa + n + 1, -1);
  for (int i = 1; i < n; i++)
    if (types[i] && !types[i - 1])
      sa[--b[(int)s[i]]] = i;
  sa[0] = n;
  sa_is_inducedSort(s, n, size, types, sa, b);
  int n1 = 0;
  for (int i = 0; i <= n; i++) {
    int j = sa[i];
    if (j > 0 && types[j] && !types[j - 1])
      sa[n1++] = j;
  }
  int *buffer = sa + n1;
  fill(buffer, sa + n + 1, -1);
  int c = 0, ppos = -1;
  buffer[sa[0] / 2] = c++;
  for (int i = 1; i < n1; i++) {
    int pos = sa[i];
    bool diff = false;
    if (ppos == -1)
      diff = true;
    else {
      for (int j = pos, k = ppos;; j++, k++) {
        if (s[j] != s[k] || types[j] != types[k]) {
          diff = true;
          break;
        } else if (j != pos &&
                   ((types[j] && !types[j - 1]) || (types[k] && !types[k - 1])))
          break;
      }
    }
    if (diff) {
      c++;
      ppos = pos;
    }
    buffer[pos / 2] = c - 1;
  }
  for (int i = n, j = n; i >= n1; i--)
    if (sa[i] >= 0)
      sa[j--] = sa[i];
  int *sa1 = sa, *s1 = sa + n + 1 - n1;
  if (c == n1)
    for (int i = 0; i < n1; i++)
      sa1[s1[i]] = i;
  else
    sa_is_rec(s1, n1 - 1, c, sa1, b);
  sa_is_countingAlphabets(s, n, size, b);
  sa_is_getBucketOffsets(s, n, true, size, b);
  for (int i = 1, j = 0; i <= n; i++)
    if (types[i] && !types[i - 1])
      s1[j++] = i;
  for (int i = 0; i < n1; i++)
    sa1[i] = s1[sa1[i]];
  fill(sa + n1, sa + n + 1, -1);
  for (int i = n1 - 1; i >= 1; i--) {
    int j = sa[i];
    sa[i] = -1;
    sa[--b[(int)s[j]]] = j;
  }
  sa_is_inducedSort(s, n, size, types, sa, b);
}

void buildSuffixArray(const int *s, int n, int size, int *sa) {
  if (n == 0)
    sa[0] = 0;
  else {
    vector<int> b(max(size, (n + 1) / 2) + 1);
    sa_is_rec(s, n, size, &sa[0], b);
  }
}

void buildSuffixArray(const string s, int n, int *sa) {
  int a[n];
  for (int i = 0; i < n; i++)
    a[i] = (int)s[i];
  int maxElem = *max_element(a, a + n);
  buildSuffixArray(a, n, maxElem + 1, sa);
}

const int MAXN = 10010;
int sa[MAXN];

string ans = "{";
ll n;

void dfs(string s, ll m) {
  if (!m) {
    ans = min(ans, s);
    return;
  }
  string t = s;
  reverse(all(t));
  s += t;
  string s1, s2;
  buildSuffixArray(s, s.size(), sa);
  rep(i, s.size()) {
    if (sa[i] < n) {
      s1 = s.substr(sa[i], n);
      break;
    }
  }
  reverse(all(s));
  buildSuffixArray(s, s.size(), sa);
  rep(i, s.size()) {
    if (sa[i] < n) {
      s2 = s.substr(sa[i], n);
      reverse(all(s2));
      break;
    }
  }
  if (s1 != s2) {
    dfs(s1, m - 1);
    dfs(s2, m - 1);
  } else
    dfs(s1, m - 1);
}

void Main() {
  ll m;
  string s;
  cin >> n >> m >> s;
  if (m < 12)
    dfs(s, m);
  else {
    char c = '{';
    rep(i, n) c = min(c, s[i]);
    ans = "";
    rep(i, n) ans += c;
  }
  pr(ans);
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  Main();
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin >>
#define Z class
#define ll long long
#define ln cout << '\n'
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n", a)
#define mem(a) memset(a, 0, sizeof(a))
#define all(c) (c).begin(), (c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i, n) for (ll i = (ll)(n)-1; i >= 0; i--)
#define REP(i, m, n) for (ll i = (ll)(m); i < (ll)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define tr(it, c) for (iter(c) it = (c).begin(); it != (c).end(); it++)
template <Z A> void pr(A a) {
  cout << a;
  ln;
}
template <Z A, Z B> void pr(A a, B b) {
  cout << a << ' ';
  pr(b);
}
template <Z A, Z B, Z C> void pr(A a, B b, C c) {
  cout << a << ' ';
  pr(b, c);
}
template <Z A, Z B, Z C, Z D> void pr(A a, B b, C c, D d) {
  cout << a << ' ';
  pr(b, c, d);
}
template <Z A> void PR(A a, ll n) {
  rep(i, n) {
    if (i)
      cout << ' ';
    cout << a[i];
  }
  ln;
}
ll check(ll n, ll m, ll x, ll y) { return x >= 0 && x < n && y >= 0 && y < m; }
const ll MAX = 1e9 + 7, MAXL = 1LL << 61, dx[4] = {-1, 0, 1, 0},
         dy[4] = {0, 1, 0, -1};
typedef pair<ll, ll> P;

void sa_is_countingAlphabets(const int *s, int n, int size, vector<int> &b,
                             bool f = false) {
  if (f || (int)b.size() / 2 >= size) {
    vector<int>::iterator a = f ? b.begin() : b.begin() + size;
    fill(a, a + size, 0);
    for (int i = 0; i < n; i++)
      a[(int)s[i]]++;
  }
}

void sa_is_getBucketOffsets(const int *s, int n, bool dir, int size,
                            vector<int> &b) {
  vector<int>::iterator a;
  if ((int)b.size() / 2 < size) {
    sa_is_countingAlphabets(s, n, size, b, true);
    a = b.begin();
  } else
    a = b.begin() + size;
  int cumsum = 1;
  if (dir) {
    for (int i = 0; i < size; i++) {
      cumsum += a[i];
      b[i] = cumsum;
    }
  } else {
    for (int i = 0; i < size; i++) {
      int x = a[i];
      b[i] = cumsum;
      cumsum += x;
    }
  }
}

void sa_is_inducedSort(const int *s, int n, int size, const vector<bool> &types,
                       int *sa, vector<int> &b) {
  sa_is_getBucketOffsets(s, n, false, size, b);
  for (int i = 0; i < n; i++) {
    int j = sa[i] - 1;
    if (j >= 0 && !types[j])
      sa[b[(int)s[j]]++] = j;
  }
  sa_is_getBucketOffsets(s, n, true, size, b);
  for (int i = n; i >= 1; i--) {
    int j = sa[i] - 1;
    if (j >= 0 && types[j])
      sa[--b[(int)s[j]]] = j;
  }
}

void sa_is_rec(const int *s, int n, int size, int *sa, vector<int> &b) {
  vector<bool> types(n + 1);
  types[n - 1] = 0;
  types[n] = 1;
  for (int i = n - 2; i >= 0; i--)
    types[i] = s[i] < s[i + 1] || (s[i] == s[i + 1] && types[i + 1]);
  sa_is_countingAlphabets(s, n, size, b);
  sa_is_getBucketOffsets(s, n, true, size, b);
  fill(sa, sa + n + 1, -1);
  for (int i = 1; i < n; i++)
    if (types[i] && !types[i - 1])
      sa[--b[(int)s[i]]] = i;
  sa[0] = n;
  sa_is_inducedSort(s, n, size, types, sa, b);
  int n1 = 0;
  for (int i = 0; i <= n; i++) {
    int j = sa[i];
    if (j > 0 && types[j] && !types[j - 1])
      sa[n1++] = j;
  }
  int *buffer = sa + n1;
  fill(buffer, sa + n + 1, -1);
  int c = 0, ppos = -1;
  buffer[sa[0] / 2] = c++;
  for (int i = 1; i < n1; i++) {
    int pos = sa[i];
    bool diff = false;
    if (ppos == -1)
      diff = true;
    else {
      for (int j = pos, k = ppos;; j++, k++) {
        if (s[j] != s[k] || types[j] != types[k]) {
          diff = true;
          break;
        } else if (j != pos &&
                   ((types[j] && !types[j - 1]) || (types[k] && !types[k - 1])))
          break;
      }
    }
    if (diff) {
      c++;
      ppos = pos;
    }
    buffer[pos / 2] = c - 1;
  }
  for (int i = n, j = n; i >= n1; i--)
    if (sa[i] >= 0)
      sa[j--] = sa[i];
  int *sa1 = sa, *s1 = sa + n + 1 - n1;
  if (c == n1)
    for (int i = 0; i < n1; i++)
      sa1[s1[i]] = i;
  else
    sa_is_rec(s1, n1 - 1, c, sa1, b);
  sa_is_countingAlphabets(s, n, size, b);
  sa_is_getBucketOffsets(s, n, true, size, b);
  for (int i = 1, j = 0; i <= n; i++)
    if (types[i] && !types[i - 1])
      s1[j++] = i;
  for (int i = 0; i < n1; i++)
    sa1[i] = s1[sa1[i]];
  fill(sa + n1, sa + n + 1, -1);
  for (int i = n1 - 1; i >= 1; i--) {
    int j = sa[i];
    sa[i] = -1;
    sa[--b[(int)s[j]]] = j;
  }
  sa_is_inducedSort(s, n, size, types, sa, b);
}

void buildSuffixArray(const int *s, int n, int size, int *sa) {
  if (n == 0)
    sa[0] = 0;
  else {
    vector<int> b(max(size, (n + 1) / 2) + 1);
    sa_is_rec(s, n, size, &sa[0], b);
  }
}

void buildSuffixArray(const string s, int n, int *sa) {
  int a[n];
  for (int i = 0; i < n; i++)
    a[i] = (int)s[i];
  int maxElem = *max_element(a, a + n);
  buildSuffixArray(a, n, maxElem + 1, sa);
}

const int MAXN = 10010;
int sa[MAXN];

string ans = "{";
ll n;

void dfs(string s, ll m) {
  if (!m) {
    ans = min(ans, s);
    return;
  }
  string t = s;
  reverse(all(t));
  s += t;
  string s1, s2;
  buildSuffixArray(s, s.size(), sa);
  rep(i, s.size()) {
    if (sa[i] < n) {
      s1 = s.substr(sa[i], n);
      break;
    }
  }
  reverse(all(s));
  buildSuffixArray(s, s.size(), sa);
  rep(i, s.size()) {
    if (sa[i] < n) {
      s2 = s.substr(sa[i], n);
      reverse(all(s2));
      break;
    }
  }
  if (s1 != s2) {
    dfs(s1, m - 1);
    dfs(s2, m - 1);
  } else
    dfs(s1, m - 1);
}

void Main() {
  ll m;
  string s;
  cin >> n >> m >> s;
  if (m < 11)
    dfs(s, m);
  else {
    char c = '{';
    rep(i, n) c = min(c, s[i]);
    ans = "";
    rep(i, n) ans += c;
  }
  pr(ans);
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  Main();
  return 0;
}