Problem p03253 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
// BEGIN CUT HERE
template <typename T, T MOD = 1000000007> struct Mint {
  T v;
  Mint() : v(0) {}
  Mint(signed v) : v(v) {}
  Mint(long long t) {
    v = t % MOD;
    if (v < 0)
      v += MOD;
  }

  Mint pow(int k) {
    Mint res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  Mint inv() { return pow(MOD - 2); }

  Mint &operator+=(Mint a) {
    v += a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator-=(Mint a) {
    v += MOD - a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator*=(Mint a) {
    v = 1LL * v * a.v % MOD;
    return *this;
  }
  Mint &operator/=(Mint a) { return (*this) *= a.inv(); }

  Mint operator+(Mint a) { return Mint(v) += a; };
  Mint operator-(Mint a) { return Mint(v) -= a; };
  Mint operator*(Mint a) { return Mint(v) *= a; };
  Mint operator/(Mint a) { return Mint(v) /= a; };

  Mint operator-() { return v ? MOD - v : v; }

  bool operator==(const Mint a) const { return v == a.v; }
  bool operator!=(const Mint a) const { return v != a.v; }

  static vector<Mint> fact, finv, invs;

  void init(int n) {
    if (n + 1 <= (signed)fact.size())
      return;
    fact.assign(n + 1, 1);
    finv.assign(n + 1, 1);
    invs.assign(n + 1, 1);

    for (int i = 1; i <= n; i++)
      fact[i] = fact[i - 1] * Mint(i);
    finv[n] = Mint(1) / fact[n];
    for (int i = n; i >= 1; i--)
      finv[i - 1] = finv[i] * Mint(i);
    for (int i = 1; i <= n; i++)
      invs[i] = finv[i] * fact[i - 1];
  }

  Mint comb(long long n, int k) {
    Mint res(1);
    for (int i = 0; i < k; i++) {
      res *= Mint(n - i);
      res /= Mint(i + 1);
    }
    return res;
  }

  Mint C(int n, int k) {
    if (n < k || k < 0)
      return Mint(0);
    return fact[n] * finv[n - k] * finv[k];
  }

  Mint P(int n, int k) {
    if (n < k || k < 0)
      return Mint(0);
    return fact[n] * finv[n - k];
  }

  Mint H(int n, int k) {
    if (n < 0 || k < 0)
      return Mint(0);
    if (!n && !k)
      return Mint(1);
    return C(n + k - 1, n);
  }

  Mint S(int n, int k) {
    Mint res;
    for (int i = 1; i <= k; i++) {
      Mint tmp = C(k, i) * Mint(i).pow(n);
      if ((k - i) & 1)
        res -= tmp;
      else
        res += tmp;
    }
    return res *= finv[k];
  }

  Mint B(int n, int k) {
    Mint res;
    for (int j = 1; j <= k; j++)
      res += S(n, j);
    return res;
  }

  Mint montmort(int n) {
    Mint res;
    for (int k = 2; k <= n; k++) {
      if (k & 1)
        res -= finv[k];
      else
        res += finv[k];
    }
    return res *= fact[n];
  }
};
template <typename T, T MOD>
vector<Mint<T, MOD>> Mint<T, MOD>::fact = vector<Mint<T, MOD>>();
template <typename T, T MOD>
vector<Mint<T, MOD>> Mint<T, MOD>::finv = vector<Mint<T, MOD>>();
template <typename T, T MOD>
vector<Mint<T, MOD>> Mint<T, MOD>::invs = vector<Mint<T, MOD>>();
// END CUT HERE

template <typename T> map<T, int> factorize(T x) {
  map<T, int> res;
  for (int i = 2; i * i <= x; i++) {
    while (x % i == 0) {
      x /= i;
      res[i]++;
    }
  }
  if (x != 1)
    res[x]++;
  return res;
}

// INSERT ABOVE HERE
signed ABC110_D() {
  int n;
  Mint<int> m;
  scanf("%d %d", &n, &m.v);

  m.init(n + 100);

  Mint<int> ans(1);
  auto x = factorize(m.v);
  for (auto p : x)
    ans *= m.H(p.second, n);

  printf("%d\n", ans.v);
  return 0;
}
/*
  verified on 2018/09/24
  https://beta.atcoder.jp/contests/abc110/tasks/abc110_d
*/

// montmort
signed ARC009_C() {
  Int n, k;
  scanf("%lld %lld", &n, &k);
  const int MMOD = 1777777777;
  using MM = Mint<long long, MMOD>;
  MM m;
  m.init(k + 1);
  MM a = m.montmort(k);
  a *= m.comb(n, k);
  printf("%lld\n", a.v);
  return 0;
}
/*
  verified on 2018/09/24
  https://beta.atcoder.jp/contests/arc009/tasks/arc009_3
*/

signed main() {
  // ABC110_D();
  ARC009_C();
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
// BEGIN CUT HERE
template <typename T, T MOD = 1000000007> struct Mint {
  T v;
  Mint() : v(0) {}
  Mint(signed v) : v(v) {}
  Mint(long long t) {
    v = t % MOD;
    if (v < 0)
      v += MOD;
  }

  Mint pow(int k) {
    Mint res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  Mint inv() { return pow(MOD - 2); }

  Mint &operator+=(Mint a) {
    v += a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator-=(Mint a) {
    v += MOD - a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator*=(Mint a) {
    v = 1LL * v * a.v % MOD;
    return *this;
  }
  Mint &operator/=(Mint a) { return (*this) *= a.inv(); }

  Mint operator+(Mint a) { return Mint(v) += a; };
  Mint operator-(Mint a) { return Mint(v) -= a; };
  Mint operator*(Mint a) { return Mint(v) *= a; };
  Mint operator/(Mint a) { return Mint(v) /= a; };

  Mint operator-() { return v ? MOD - v : v; }

  bool operator==(const Mint a) const { return v == a.v; }
  bool operator!=(const Mint a) const { return v != a.v; }

  static vector<Mint> fact, finv, invs;

  void init(int n) {
    if (n + 1 <= (signed)fact.size())
      return;
    fact.assign(n + 1, 1);
    finv.assign(n + 1, 1);
    invs.assign(n + 1, 1);

    for (int i = 1; i <= n; i++)
      fact[i] = fact[i - 1] * Mint(i);
    finv[n] = Mint(1) / fact[n];
    for (int i = n; i >= 1; i--)
      finv[i - 1] = finv[i] * Mint(i);
    for (int i = 1; i <= n; i++)
      invs[i] = finv[i] * fact[i - 1];
  }

  Mint comb(long long n, int k) {
    Mint res(1);
    for (int i = 0; i < k; i++) {
      res *= Mint(n - i);
      res /= Mint(i + 1);
    }
    return res;
  }

  Mint C(int n, int k) {
    if (n < k || k < 0)
      return Mint(0);
    return fact[n] * finv[n - k] * finv[k];
  }

  Mint P(int n, int k) {
    if (n < k || k < 0)
      return Mint(0);
    return fact[n] * finv[n - k];
  }

  Mint H(int n, int k) {
    if (n < 0 || k < 0)
      return Mint(0);
    if (!n && !k)
      return Mint(1);
    return C(n + k - 1, n);
  }

  Mint S(int n, int k) {
    Mint res;
    for (int i = 1; i <= k; i++) {
      Mint tmp = C(k, i) * Mint(i).pow(n);
      if ((k - i) & 1)
        res -= tmp;
      else
        res += tmp;
    }
    return res *= finv[k];
  }

  Mint B(int n, int k) {
    Mint res;
    for (int j = 1; j <= k; j++)
      res += S(n, j);
    return res;
  }

  Mint montmort(int n) {
    Mint res;
    for (int k = 2; k <= n; k++) {
      if (k & 1)
        res -= finv[k];
      else
        res += finv[k];
    }
    return res *= fact[n];
  }
};
template <typename T, T MOD>
vector<Mint<T, MOD>> Mint<T, MOD>::fact = vector<Mint<T, MOD>>();
template <typename T, T MOD>
vector<Mint<T, MOD>> Mint<T, MOD>::finv = vector<Mint<T, MOD>>();
template <typename T, T MOD>
vector<Mint<T, MOD>> Mint<T, MOD>::invs = vector<Mint<T, MOD>>();
// END CUT HERE

template <typename T> map<T, int> factorize(T x) {
  map<T, int> res;
  for (int i = 2; i * i <= x; i++) {
    while (x % i == 0) {
      x /= i;
      res[i]++;
    }
  }
  if (x != 1)
    res[x]++;
  return res;
}

// INSERT ABOVE HERE
signed ABC110_D() {
  int n;
  Mint<int> m;
  scanf("%d %d", &n, &m.v);

  m.init(n + 100);

  Mint<int> ans(1);
  auto x = factorize(m.v);
  for (auto p : x)
    ans *= m.H(p.second, n);

  printf("%d\n", ans.v);
  return 0;
}
/*
  verified on 2018/09/24
  https://beta.atcoder.jp/contests/abc110/tasks/abc110_d
*/

// montmort
signed ARC009_C() {
  Int n, k;
  scanf("%lld %lld", &n, &k);
  const int MMOD = 1777777777;
  using MM = Mint<long long, MMOD>;
  MM m;
  m.init(k + 1);
  MM a = m.montmort(k);
  a *= m.comb(n, k);
  printf("%lld\n", a.v);
  return 0;
}
/*
  verified on 2018/09/24
  https://beta.atcoder.jp/contests/arc009/tasks/arc009_3
*/

signed main() {
  ABC110_D();
  // ARC009_C();
  return 0;
}