Problem p03234 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

const int N = 404, MOD = 1e9 + 7;

namespace {
int Mul(int x, int y) { return 1LL * x * y % MOD; }
int Dec(int x, int y) { return (x -= y) < 0 ? x + MOD : x; }
int Add(int x, int y) { return (x += y) >= MOD ? x - MOD : x; }
int Kissme(int x, int y) {
  int c = 1;
  while (y) {
    if (y & 1)
      c = Mul(c, x);
    x = Mul(x, x);
    y >>= 1;
  }
  return c;
}
} // namespace

struct Segment {
  int u, v;

  bool Intersect(const Segment &rhs) const {
    return ((rhs.u > u) & (rhs.u < v)) ^ ((rhs.v > u) & (rhs.v < v));
  }
} seg[N];

int fa[N], n, K, mi[N], mx[N], G[N], f[N][N], vis[N], Ans, IG[N];

int Find(int x) { return fa[x] == x ? x : fa[x] = Find(fa[x]); }

void Merge(int x, int y) {
  int fx = Find(x), fy = Find(y);
  if (fx != fy) {
    fa[fx] = fy;
    mx[fy] = max(mx[fy], mx[fx]);
    mi[fy] = min(mi[fy], mi[fx]);
  }
}

int main(void) {
  scanf("%d%d", &n, &K);
  for (int i = 1; i <= 2 * n; i++)
    fa[i] = mx[i] = mi[i] = i;
  for (int i = 1; i <= K; i++) {
    scanf("%d%d", &seg[i].u, &seg[i].v);
    vis[seg[i].u] = vis[seg[i].v] = 1;

    if (seg[i].u > seg[i].v)
      swap(seg[i].u, seg[i].v);
    Merge(seg[i].u, seg[i].v);
    for (int j = 1; j < i; j++)
      if (seg[i].Intersect(seg[j]))
        Merge(seg[i].u, seg[j].u);
  }

  G[0] = 1;
  IG[0] = 1;
  for (int i = 2; i <= 2 * n; i += 2) {
    G[i] = Mul(G[i - 2], i - 1);
    IG[i] = Kissme(G[i], MOD - 2);
  }

  for (int l = 0; l < 2 * n; l++)
    for (int i = 1, j = 1 + l; j <= 2 * n; i++, j++) {
      if (mx[Find(i)] > j || mi[Find(i)] < i || mx[Find(j)] > j ||
          mi[Find(j)] < i)
        continue;
      bool flg = 0;
      for (int k = 1; k <= K; k++)
        if (seg[k].Intersect({i, j}))
          flg = 1;
      if (flg)
        continue;

      int X = 0, Y = 0;
      for (int k = 1; k < i; k++)
        X += !vis[k];
      for (int k = j + 1; k <= 2 * n; k++)
        X += !vis[k];
      for (int k = i; k <= j; k++)
        Y += !vis[k];

      f[i][j] = Mul(G[X], G[Y]);
      //      printf("f[%d][%d] = %d\n", i, j, f[i][j]);

      for (int k = j - 1, Z = !vis[j]; k > i; Z += !vis[k--])
        if (f[i][k]) {
          assert(~(X + Z) & 1);
          f[i][j] = Dec(f[i][j], Mul(f[i][k], Mul(IG[X + Z], Mul(G[Z], G[X]))));
        }

      //      printf("f[%d][%d] = %d\n", i, j, f[i][j]);
      Ans = Add(Ans, f[i][j]);
    }
  cout << Ans << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int N = 604, MOD = 1e9 + 7;

namespace {
int Mul(int x, int y) { return 1LL * x * y % MOD; }
int Dec(int x, int y) { return (x -= y) < 0 ? x + MOD : x; }
int Add(int x, int y) { return (x += y) >= MOD ? x - MOD : x; }
int Kissme(int x, int y) {
  int c = 1;
  while (y) {
    if (y & 1)
      c = Mul(c, x);
    x = Mul(x, x);
    y >>= 1;
  }
  return c;
}
} // namespace

struct Segment {
  int u, v;

  bool Intersect(const Segment &rhs) const {
    return ((rhs.u > u) & (rhs.u < v)) ^ ((rhs.v > u) & (rhs.v < v));
  }
} seg[N];

int fa[N], n, K, mi[N], mx[N], G[N], f[N][N], vis[N], Ans, IG[N];

int Find(int x) { return fa[x] == x ? x : fa[x] = Find(fa[x]); }

void Merge(int x, int y) {
  int fx = Find(x), fy = Find(y);
  if (fx != fy) {
    fa[fx] = fy;
    mx[fy] = max(mx[fy], mx[fx]);
    mi[fy] = min(mi[fy], mi[fx]);
  }
}

int main(void) {
  scanf("%d%d", &n, &K);
  for (int i = 1; i <= 2 * n; i++)
    fa[i] = mx[i] = mi[i] = i;
  for (int i = 1; i <= K; i++) {
    scanf("%d%d", &seg[i].u, &seg[i].v);
    vis[seg[i].u] = vis[seg[i].v] = 1;

    if (seg[i].u > seg[i].v)
      swap(seg[i].u, seg[i].v);
    Merge(seg[i].u, seg[i].v);
    for (int j = 1; j < i; j++)
      if (seg[i].Intersect(seg[j]))
        Merge(seg[i].u, seg[j].u);
  }

  G[0] = 1;
  IG[0] = 1;
  for (int i = 2; i <= 2 * n; i += 2) {
    G[i] = Mul(G[i - 2], i - 1);
    IG[i] = Kissme(G[i], MOD - 2);
  }

  for (int l = 0; l < 2 * n; l++)
    for (int i = 1, j = 1 + l; j <= 2 * n; i++, j++) {
      if (mx[Find(i)] > j || mi[Find(i)] < i || mx[Find(j)] > j ||
          mi[Find(j)] < i)
        continue;
      bool flg = 0;
      for (int k = 1; k <= K; k++)
        if (seg[k].Intersect({i, j}))
          flg = 1;
      if (flg)
        continue;

      int X = 0, Y = 0;
      for (int k = 1; k < i; k++)
        X += !vis[k];
      for (int k = j + 1; k <= 2 * n; k++)
        X += !vis[k];
      for (int k = i; k <= j; k++)
        Y += !vis[k];

      f[i][j] = Mul(G[X], G[Y]);
      //      printf("f[%d][%d] = %d\n", i, j, f[i][j]);

      for (int k = j - 1, Z = !vis[j]; k > i; Z += !vis[k--])
        if (f[i][k]) {
          assert(~(X + Z) & 1);
          f[i][j] = Dec(f[i][j], Mul(f[i][k], Mul(IG[X + Z], Mul(G[Z], G[X]))));
        }

      //      printf("f[%d][%d] = %d\n", i, j, f[i][j]);
      Ans = Add(Ans, f[i][j]);
    }
  cout << Ans << endl;
  return 0;
}