Problem p03234 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios {
  fast_ios() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  };
} fast_ios_;
#define FOR(i, begin, end)                                                     \
  for (int i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \
  for (int i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, pair<T1, T2> &pa) {
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
#define dbg(x)                                                                 \
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

int N, K;
vector<int> con;
int avi[602];

constexpr lint MOD = 1000000007;
int leftmost[602][602], rightmost[602][602];
lint dp[602][602];

lint extgcd(lint a, lint b, lint &x, lint &y) {
  lint d = a;
  if (b != 0)
    d = extgcd(b, a % b, y, x), y -= (a / b) * x;
  else
    x = 1, y = 0;
  return d;
}
vector<lint> fac, facInv, inv;
void facInit(int nmax) {
  fac = facInv = inv = vector<lint>(nmax + 1, 1);
  for (int i = 2; i <= nmax; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    facInv[i] = facInv[i - 1] * inv[i] % MOD;
  }
}
lint nCr(int n, int r) {
  if (n < r || r < 0)
    return 0;
  return (fac[n] * facInv[r] % MOD) * facInv[n - r] % MOD;
}
lint power(lint x, lint n, lint mod = MOD) {
  lint ans = 1;
  while (n > 0) {
    if (n & 1)
      (ans *= x) %= mod;
    (x *= x) %= mod;
    n >>= 1;
  }
  return ans;
}
lint modinv(lint x, lint mod = MOD) {
  lint ans, y;
  extgcd(x, mod, ans, y);
  ans %= mod;
  return ans < 0 ? ans + mod : ans;
}
lint doublefac(lint n) {
  lint k = (n + 1) / 2;
  if (n & 1)
    return fac[k * 2] * power(facInv[2], k) % MOD * modinv(fac[k]) % MOD;
  else
    return fac[k] * power(facInv[2], k) % MOD;
}

lint solve(int l, int r) {
  lint ans = 0;
  int ca = avi[r] - avi[l - 1];
  if (leftmost[l][r] < l || rightmost[l][r] > r || (ca & 1))
    return ans;

  ans = doublefac(max(ca - 1, 0));

  FOR(i, l + 1, r) // lからiまでが連結
  {
    if (rightmost[l][i] > i)
      continue;
    int c2 = avi[r] - avi[i];
    if (c2 & 1)
      continue;

    ans += MOD - dp[l][i] * doublefac(max(c2 - 1, 0)) % MOD;
  }
  ans %= MOD;
  dp[l][r] = ans;
  return ans * doublefac(max(avi[l - 1] + avi[N * 2] - avi[r] - 1, 0)) % MOD;
}

int main() {
  memset(dp, 0, sizeof(dp));
  cin >> N >> K;
  con.resize(N * 2 + 1);

  facInit(N * 3);

  avi[0] = 0;
  FOR(i, 1, N * 2 + 1) avi[i] = 1;

  REP(i, 2 * N + 1) REP(j, 2 * N + 1) {
    leftmost[i][j] = i;
    rightmost[i][j] = j;
  }

  REP(_, K) {
    int A, B;
    cin >> A >> B;
    con[A] = B;
    con[B] = A;
    avi[A] = avi[B] = 0;
    if (B < A)
      swap(A, B);
    FOR(i, 1, A + 1)
    FOR(j, A, 2 * N + 1) leftmost[i][j] = min(leftmost[i][j], B),
                         rightmost[i][j] = max(rightmost[i][j], B);
    FOR(i, 1, B + 1)
    FOR(j, B, 2 * N + 1) leftmost[i][j] = min(leftmost[i][j], A),
                         rightmost[i][j] = max(rightmost[i][j], A);
  }

  REP(i, N * 2) avi[i + 1] += avi[i];

  lint ans = 0;
  FOR(l, 1, 2 * N) FOR(r, l + 1, 2 * N + 1) ans = (ans + solve(l, r)) % MOD;
  cout << ans << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios {
  fast_ios() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  };
} fast_ios_;
#define FOR(i, begin, end)                                                     \
  for (int i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \
  for (int i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, pair<T1, T2> &pa) {
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
#define dbg(x)                                                                 \
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

int N, K;
vector<int> con;
int avi[602];

constexpr lint MOD = 1000000007;
int leftmost[602][602], rightmost[602][602];
lint dp[602][602];

lint extgcd(lint a, lint b, lint &x, lint &y) {
  lint d = a;
  if (b != 0)
    d = extgcd(b, a % b, y, x), y -= (a / b) * x;
  else
    x = 1, y = 0;
  return d;
}
vector<lint> fac, facInv, inv;
void facInit(int nmax) {
  fac = facInv = inv = vector<lint>(nmax + 1, 1);
  for (int i = 2; i <= nmax; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    facInv[i] = facInv[i - 1] * inv[i] % MOD;
  }
}
lint nCr(int n, int r) {
  if (n < r || r < 0)
    return 0;
  return (fac[n] * facInv[r] % MOD) * facInv[n - r] % MOD;
}
lint power(lint x, lint n, lint mod = MOD) {
  lint ans = 1;
  while (n > 0) {
    if (n & 1)
      (ans *= x) %= mod;
    (x *= x) %= mod;
    n >>= 1;
  }
  return ans;
}
lint modinv(lint x, lint mod = MOD) {
  lint ans, y;
  extgcd(x, mod, ans, y);
  ans %= mod;
  return ans < 0 ? ans + mod : ans;
}
lint doublefac(lint n) {
  lint k = (n + 1) / 2;
  if (n & 1)
    return fac[k * 2] * power(facInv[2], k) % MOD * power(fac[k], MOD - 2) %
           MOD;
  else
    return fac[k] * power(facInv[2], k) % MOD;
}

lint solve(int l, int r) {
  lint ans = 0;
  int ca = avi[r] - avi[l - 1];
  if (leftmost[l][r] < l || rightmost[l][r] > r || (ca & 1))
    return ans;

  ans = doublefac(max(ca - 1, 0));

  FOR(i, l + 1, r) // lからiまでが連結
  {
    if (rightmost[l][i] > i)
      continue;
    int c2 = avi[r] - avi[i];
    if (c2 & 1)
      continue;

    ans += MOD - dp[l][i] * doublefac(max(c2 - 1, 0)) % MOD;
  }
  ans %= MOD;
  dp[l][r] = ans;
  return ans * doublefac(max(avi[l - 1] + avi[N * 2] - avi[r] - 1, 0)) % MOD;
}

int main() {
  memset(dp, 0, sizeof(dp));
  cin >> N >> K;
  con.resize(N * 2 + 1);

  facInit(N * 3);

  avi[0] = 0;
  FOR(i, 1, N * 2 + 1) avi[i] = 1;

  REP(i, 2 * N + 1) REP(j, 2 * N + 1) {
    leftmost[i][j] = i;
    rightmost[i][j] = j;
  }

  REP(_, K) {
    int A, B;
    cin >> A >> B;
    con[A] = B;
    con[B] = A;
    avi[A] = avi[B] = 0;
    if (B < A)
      swap(A, B);
    FOR(i, 1, A + 1)
    FOR(j, A, 2 * N + 1) leftmost[i][j] = min(leftmost[i][j], B),
                         rightmost[i][j] = max(rightmost[i][j], B);
    FOR(i, 1, B + 1)
    FOR(j, B, 2 * N + 1) leftmost[i][j] = min(leftmost[i][j], A),
                         rightmost[i][j] = max(rightmost[i][j], A);
  }

  REP(i, N * 2) avi[i + 1] += avi[i];

  lint ans = 0;
  FOR(l, 1, 2 * N) FOR(r, l + 1, 2 * N + 1) ans = (ans + solve(l, r)) % MOD;
  cout << ans << endl;
}