Problem p03969 (C++)

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

inline int gi() {
  char c = getchar();
  while (c < '0' || c > '9')
    c = getchar();
  int sum = 0;
  while ('0' <= c && c <= '9')
    sum = sum * 10 + c - 48, c = getchar();
  return sum;
}

typedef long long ll;
const int maxn = 55, maxm = 105, mod = 1e9 + 7;

int n, m, col, fac[maxm << 1], ifac[maxm << 1];

struct edge {
  int to, next;
} e[maxm * 2];
int h[maxn], tot;

inline void add(int u, int v) {
  e[++tot] = (edge){v, h[u]}, h[u] = tot;
  e[++tot] = (edge){u, h[v]};
  h[v] = tot;
}

int dfn[maxn], low[maxn], Time, top, bccno[maxn], cnt, siz_p[maxn], siz_e[maxn];
pair<int, int> stk[maxn];
vector<int> vec[maxn];

void dfs(int u, int fa) {
  dfn[u] = low[u] = ++Time;
  for (int i = h[u], v; v = e[i].to, i; i = e[i].next)
    if (v != fa) {
      if (!dfn[v]) {
        stk[++top] = make_pair(u, v);
        dfs(v, u);
        low[u] = min(low[u], low[v]);
        if (dfn[u] <= low[v]) {
          ++cnt;
          while (1) {
            int x = stk[top].first, y = stk[top].second;
            ++siz_e[cnt];
            if (bccno[x] != cnt)
              bccno[x] = cnt, ++siz_p[cnt], vec[cnt].push_back(x);
            if (bccno[y] != cnt)
              bccno[y] = cnt, ++siz_p[cnt], vec[cnt].push_back(y);
            --top;
            if (x == u && y == v)
              break;
          }
        }
      } else if (dfn[v] < dfn[u])
        stk[++top] = make_pair(u, v), low[u] = min(low[u], dfn[v]);
    }
}

inline int fpow(int x, int k) {
  int res = 1;
  while (k) {
    if (k & 1)
      res = (ll)res * x % mod;
    x = (ll)x * x % mod;
    k >>= 1;
  }
  return res;
}

inline int C(int n, int m) {
  return (ll)fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main() {
  n = gi();
  m = gi();
  col = gi();

  for (int i = 1; i <= m; ++i)
    add(gi(), gi());

  for (int i = 1; i <= n; ++i)
    if (!dfn[i])
      dfs(i, 0);

  fac[0] = ifac[0] = ifac[1] = 1;
  for (int i = 1; i <= m + col; ++i)
    fac[i] = (ll)fac[i - 1] * i % mod;
  for (int i = 2; i <= m + col; ++i)
    ifac[i] = (ll)(mod - mod / i) * ifac[mod % i] % mod;
  for (int i = 2; i <= m + col; ++i)
    ifac[i] = (ll)ifac[i - 1] * ifac[i] % mod;

  int ans1 = 1, ans2 = 1, ans3 = 1;
  for (int i = 1; i <= cnt; ++i)
    if (siz_e[i] == 1)
      ans1 = (ll)ans1 * col % mod;
    else if (siz_e[i] == siz_p[i]) {
      int sum = 0;
      for (int j = 1; j <= siz_e[i]; ++j) {
        sum += fpow(col, __gcd(j, siz_p[i]));
        if (sum >= mod)
          sum -= mod;
      }
      ans2 = (ll)ans2 * sum % mod * fpow(siz_e[i], mod - 2) % mod;
    } else
      ans3 = (ll)ans3 * C(siz_e[i] + col - 1, col - 1) % mod;

  printf("%lld\n", (ll)ans1 * ans2 % mod * ans3 % mod);

  return 0;
}


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

inline int gi() {
  char c = getchar();
  while (c < '0' || c > '9')
    c = getchar();
  int sum = 0;
  while ('0' <= c && c <= '9')
    sum = sum * 10 + c - 48, c = getchar();
  return sum;
}

typedef long long ll;
const int maxn = 55, maxm = 105, mod = 1e9 + 7;

int n, m, col, fac[maxm << 1], ifac[maxm << 1];

struct edge {
  int to, next;
} e[maxm * 2];
int h[maxn], tot;

inline void add(int u, int v) {
  e[++tot] = (edge){v, h[u]}, h[u] = tot;
  e[++tot] = (edge){u, h[v]};
  h[v] = tot;
}

int dfn[maxn], low[maxn], Time, top, bccno[maxn], cnt, siz_p[maxn], siz_e[maxn];
pair<int, int> stk[maxm];
vector<int> vec[maxn];

void dfs(int u, int fa) {
  dfn[u] = low[u] = ++Time;
  for (int i = h[u], v; v = e[i].to, i; i = e[i].next)
    if (v != fa) {
      if (!dfn[v]) {
        stk[++top] = make_pair(u, v);
        dfs(v, u);
        low[u] = min(low[u], low[v]);
        if (dfn[u] <= low[v]) {
          ++cnt;
          while (1) {
            int x = stk[top].first, y = stk[top].second;
            ++siz_e[cnt];
            if (bccno[x] != cnt)
              bccno[x] = cnt, ++siz_p[cnt], vec[cnt].push_back(x);
            if (bccno[y] != cnt)
              bccno[y] = cnt, ++siz_p[cnt], vec[cnt].push_back(y);
            --top;
            if (x == u && y == v)
              break;
          }
        }
      } else if (dfn[v] < dfn[u])
        stk[++top] = make_pair(u, v), low[u] = min(low[u], dfn[v]);
    }
}

inline int fpow(int x, int k) {
  int res = 1;
  while (k) {
    if (k & 1)
      res = (ll)res * x % mod;
    x = (ll)x * x % mod;
    k >>= 1;
  }
  return res;
}

inline int C(int n, int m) {
  return (ll)fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}

int main() {
  n = gi();
  m = gi();
  col = gi();

  for (int i = 1; i <= m; ++i)
    add(gi(), gi());

  for (int i = 1; i <= n; ++i)
    if (!dfn[i])
      dfs(i, 0);

  fac[0] = ifac[0] = ifac[1] = 1;
  for (int i = 1; i <= m + col; ++i)
    fac[i] = (ll)fac[i - 1] * i % mod;
  for (int i = 2; i <= m + col; ++i)
    ifac[i] = (ll)(mod - mod / i) * ifac[mod % i] % mod;
  for (int i = 2; i <= m + col; ++i)
    ifac[i] = (ll)ifac[i - 1] * ifac[i] % mod;

  int ans1 = 1, ans2 = 1, ans3 = 1;
  for (int i = 1; i <= cnt; ++i)
    if (siz_e[i] == 1)
      ans1 = (ll)ans1 * col % mod;
    else if (siz_e[i] == siz_p[i]) {
      int sum = 0;
      for (int j = 1; j <= siz_e[i]; ++j) {
        sum += fpow(col, __gcd(j, siz_p[i]));
        if (sum >= mod)
          sum -= mod;
      }
      ans2 = (ll)ans2 * sum % mod * fpow(siz_e[i], mod - 2) % mod;
    } else
      ans3 = (ll)ans3 * C(siz_e[i] + col - 1, col - 1) % mod;

  printf("%lld\n", (ll)ans1 * ans2 % mod * ans3 % mod);

  return 0;
}