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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define foreach(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define all(c) begin(c), end(c)
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

vvi gettable(const vi &a, const vector<tuple<int, int, int>> &rs) {
  int n = a.size();
  vector<vector<unordered_set<int>>> dp(n, vector<unordered_set<int>>(n));
  rep(i, n) dp[i][(i + 1) % n].insert(a[i]);
  // per(i,n) repi(j,i+2,n+1) repi(k,i+1,j)
  //	for(auto r:rs){
  //		int x1,x2,y; tie(x1,x2,y)=r;
  //		if(dp[i][k%n].count(x1) && dp[k][j%n].count(x2))
  //			dp[i][j%n].insert(y);
  //	}
  repi(len, 2, n + 1) rep(i, n) repi(j, 1, len) for (auto r : rs) {
    int x1, x2, y;
    tie(x1, x2, y) = r;
    if (dp[i][(i + j) % n].count(x1) &&
        dp[(i + j) % n][(i + len) % n].count(x2))
      dp[i][(i + len) % n].insert(y);
  }
  vvi res(n, vi(n));
  rep(i, n) rep(j, n) for (int x : dp[i][j]) if (x >= 0) res[i][j] |= 1 << x;
  return res;
}

int calc(const vi &a, const vi &b, const vvi &ta, const vvi &tb) {
  int n = a.size(), m = b.size();

  vvi dp(n + 1, vi(m + 1, -1e8));
  dp[n][m] = 0;
  peri(j, 1, n + 1) peri(l, 1, m + 1) rep(i, j)
      rep(k, l) if (ta[i][j % n] & tb[k][l % m]) dp[i][k] =
          max(dp[i][k], dp[j][l] + 1);
  return dp[0][0];
}

void rotate(vi &a, vvi &ta) {
  rotate(begin(a), begin(a) + 1, end(a));
  rotate(begin(ta), begin(ta) + 1, end(ta));
  rep(i, ta.size()) rotate(begin(ta[i]), begin(ta[i]) + 1, end(ta[i]));
}

int main() {
  for (int n, m, r; cin >> n >> m >> r, n | m | r;) {
    vi a(n), b(m);
    rep(i, n) cin >> a[i], a[i]--;
    rep(i, m) cin >> b[i], b[i]--;

    vector<tuple<int, int, int>> rs;
    for (int i = 0, c = 0; i < r; i++) {
      int k;
      cin >> k;
      vi xs(k + 1);
      rep(j, k + 1) {
        cin >> xs[j];
        xs[j]--;
      }
      int p = xs[0];
      repi(j, 1, k - 1) {
        rs.emplace_back(p, xs[j], --c);
        p = c;
      }
      rs.emplace_back(p, xs[k - 1], xs[k]);
    }

    vvi ta = gettable(a, rs), tb = gettable(b, rs);

    int res = -1;
    rep(i, n) {
      rep(j, m) {
        res = max(res, calc(a, b, ta, tb));
        rotate(b, tb);
      }
      rotate(a, ta);
    }

    cout << res << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define foreach(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define all(c) begin(c), end(c)
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

vvi gettable(const vi &a, const vector<tuple<int, int, int>> &rs) {
  int n = a.size();
  vector<vector<unordered_set<int>>> dp(n + 1,
                                        vector<unordered_set<int>>(n + 1));
  rep(i, n) dp[i][i + 1].insert(a[i]);
  per(i, n) repi(j, i + 2, n + 1) repi(k, i + 1, j) for (auto r : rs) {
    int x1, x2, y;
    tie(x1, x2, y) = r;
    if (dp[i][k].count(x1) && dp[k][j].count(x2))
      dp[i][j].insert(y);
  }
  vvi res(n + 1, vi(n + 1));
  rep(i, n + 1) rep(j, n + 1) for (int x : dp[i][j]) if (x >= 0) res[i][j] |=
      1 << x;
  return res;
}

int calc(const vi &a, const vi &b, const vvi &ta, const vvi &tb) {
  int n = a.size(), m = b.size();

  vvi dp(n + 1, vi(m + 1, -1e8));
  dp[n][m] = 0;
  peri(j, 1, n + 1) peri(l, 1, m + 1) rep(i, j)
      rep(k, l) if (ta[i][j] & tb[k][l]) dp[i][k] = max(dp[i][k], dp[j][l] + 1);
  return dp[0][0];
}

int main() {
  for (int n, m, r; cin >> n >> m >> r, n | m | r;) {
    vi a(n), b(m);
    rep(i, n) cin >> a[i], a[i]--;
    rep(i, m) cin >> b[i], b[i]--;

    vector<tuple<int, int, int>> rs;
    for (int i = 0, c = 0; i < r; i++) {
      int k;
      cin >> k;
      vi xs(k + 1);
      rep(j, k + 1) {
        cin >> xs[j];
        xs[j]--;
      }
      int p = xs[0];
      repi(j, 1, k - 1) {
        rs.emplace_back(p, xs[j], --c);
        p = c;
      }
      rs.emplace_back(p, xs[k - 1], xs[k]);
    }

    int res = -1;
    rep(i, n) {
      vvi ta = gettable(a, rs);
      rep(j, m) {
        vvi tb = gettable(b, rs);
        res = max(res, calc(a, b, ta, tb));
        rotate(begin(b), begin(b) + 1, end(b));
      }
      rotate(begin(a), begin(a) + 1, end(a));
    }

    cout << res << endl;
  }
}