Problem p02728 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <vector>

long long pow(long long n, long long p, long long k) { // n^k(mod p)
  if (!k)
    return 1;
  long long a = pow(n, p, k >> 1);
  a = a * a % p;
  if (k & 1)
    a = a * n % p;
  return a;
}
void euclid(long long &a, long long &b, long long p) { // a>=b A*b+B*(a-a/b*b)=1
  if (a == 1) {
    a = 1;
  } else {
    long long A = b, B = a % b;
    euclid(A, B, p);
    b = (A - (p + a / b) % p * B % p + p) % p;
    a = B;
  }
}
long long rev(long long n, long long p) { // nの逆元 n*x-p*y=1
  // long long q = p;
  // euclid(p, n, p);
  // return n % q;
  return pow(n, p, p - 2);
}
long long bino(long long n, long long m, long long p) { // nCm(mod p)
  long long ans = 1, div = 1;
  for (int i = 0; i < m; i++) {
    ans = (n - i) * ans % p;
    div = div * (i + 1) % p;
  }
  return ans * rev(div, p) % p;
}
struct modint {
  long long num;
  long long p;
  modint() {
    num = 0;
    p = 1000000007;
  }
  modint(int x) {
    p = 1000000007;
    num = (long long)x % p;
  }
  modint(long long x) {
    p = 1000000007;
    num = x % p;
  }
  modint operator+(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num + other.num) % p;
    return ret;
  }
  modint operator+(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num + (other % p)) % p;
    return ret;
  }
  modint operator-(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num - other.num + p) % p;
    return ret;
  }
  modint operator-(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num - (other % p) + p) % p;
    return ret;
  }
  modint operator*(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * other.num) % p;
    return ret;
  }
  modint operator*(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * (other % p)) % p;
    return ret;
  }
  modint operator/(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * rev(other.num, p)) % p;
    return ret;
  }
  modint operator/(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * rev(other % p, p)) % p;
    return ret;
  }
  void operator+=(const long long &other) { num = (num + other) % p; }
  void operator+=(const modint &other) { num = (num + other.num) % p; }
  void operator-=(const long long &other) { num = (num - other + p) % p; }
  void operator-=(const modint &other) { num = (num - other.num + p) % p; }
  void operator*=(const long long &other) { num = (num * other) % p; }
  void operator*=(const modint &other) { num = (num * other.num) % p; }
};
std::ostream &operator<<(std::ostream &os, const modint &x) {
  std::cout << x.num;
  return os;
}

using namespace std;

struct combination {
  vector<modint> li;
  vector<modint> rev;
  combination(int size = 202000) {
    li = vector<modint>(size);
    rev = vector<modint>(size);
    li[0] = 1;
    for (int i = 1; i < size; i++)
      li[i] = li[i - 1] * i;
    rev.back() = modint(1) / li.back();
    for (int i = size - 1; i > 0; i--)
      rev[i - 1] = rev[i] * i;
  }
  modint nCk(int n, int k) {
    if (k <= 0 || n <= k)
      return 1;
    return li[n] * rev[k] * rev[n - k];
  }
} comb(20);

struct DP {
  modint c;
  int t;
  DP() {
    c = modint(1);
    t = 0;
  }
  void operator+=(const DP &other) {
    t += other.t;
    c *= comb.nCk(t, other.t) * other.c;
  }
  DP operator+(const DP &other) {
    DP ret;
    ret.t = other.t + t;
    ret.c = c * comb.nCk(ret.t, other.t) * other.c;
    return ret;
  }
  DP operator-(const DP &other) {
    DP ret(*this);
    ret.c = ret.c / (comb.nCk(t, other.t) * other.c);
    ret.t -= other.t;
    return ret;
  }
  DP addroot() {
    DP ret(*this);
    ret.t++;
    return ret;
  }
};

void dfs1(int child, vector<vector<int>> &da, vector<DP> &ans, int pare = -1) {
  for (int i = 0; i < da[child].size(); i++) {
    if (da[child][i] == pare)
      continue;
    dfs1(da[child][i], da, ans, child);
    ans[child] += ans[da[child][i]].addroot();
  }
}

void dfs2(int child, vector<vector<int>> &da, vector<DP> &ans,
          const DP &dp = DP(), int pare = -1) {
  if (pare != -1)
    ans[child] += dp;
  int size = da[child].size();
  vector<DP> dpL(size + 1), dpR(size + 1);

  for (int i = 0; i < size; i++) {
    dpL[i + 1] = dpL[i];
    if (da[child][i] == pare)
      dpL[i + 1] += dp;
    else
      dpL[i + 1] += ans[da[child][i]].addroot();
  }

  for (int i = size; i > 0; i--) {
    dpR[i - 1] = dpR[i];
    if (da[child][i - 1] == pare)
      dpR[i - 1] += dp;
    else
      dpR[i - 1] += ans[da[child][i - 1]].addroot();
  }
  for (int i = 0; i < size; i++) {
    int next = da[child][i];
    if (next == pare)
      continue;
    // printf("%d %d\n",child, next);
    dfs2(next, da, ans, (dpL[i] + dpR[i + 1]).addroot(), child);
  }
}

void rooting(vector<vector<int>> &da, vector<DP> &ans) {
  dfs1(0, da, ans);
  dfs2(0, da, ans);
}

int main() {
  int n;
  cin >> n;
  vector<vector<int>> da(n, vector<int>(0));
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    da[a].push_back(b);
    da[b].push_back(a);
  }
  vector<DP> ans(n);
  rooting(da, ans);
  for (int i = 0; i < n; i++)
    cout << ans[i].c << endl;
}

Fixed submission:
#include <iostream>
#include <vector>

long long pow(long long n, long long p, long long k) { // n^k(mod p)
  if (!k)
    return 1;
  long long a = pow(n, p, k >> 1);
  a = a * a % p;
  if (k & 1)
    a = a * n % p;
  return a;
}
void euclid(long long &a, long long &b, long long p) { // a>=b A*b+B*(a-a/b*b)=1
  if (a == 1) {
    a = 1;
  } else {
    long long A = b, B = a % b;
    euclid(A, B, p);
    b = (A - (p + a / b) % p * B % p + p) % p;
    a = B;
  }
}
long long rev(long long n, long long p) { // nの逆元 n*x-p*y=1
  // long long q = p;
  // euclid(p, n, p);
  // return n % q;
  return pow(n, p, p - 2);
}
long long bino(long long n, long long m, long long p) { // nCm(mod p)
  long long ans = 1, div = 1;
  for (int i = 0; i < m; i++) {
    ans = (n - i) * ans % p;
    div = div * (i + 1) % p;
  }
  return ans * rev(div, p) % p;
}
struct modint {
  long long num;
  long long p;
  modint() {
    num = 0;
    p = 1000000007;
  }
  modint(int x) {
    p = 1000000007;
    num = (long long)x % p;
  }
  modint(long long x) {
    p = 1000000007;
    num = x % p;
  }
  modint operator+(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num + other.num) % p;
    return ret;
  }
  modint operator+(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num + (other % p)) % p;
    return ret;
  }
  modint operator-(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num - other.num + p) % p;
    return ret;
  }
  modint operator-(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num - (other % p) + p) % p;
    return ret;
  }
  modint operator*(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * other.num) % p;
    return ret;
  }
  modint operator*(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * (other % p)) % p;
    return ret;
  }
  modint operator/(const modint &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * rev(other.num, p)) % p;
    return ret;
  }
  modint operator/(const long long &other) {
    modint ret;
    ret.p = p;
    ret.num = (num * rev(other % p, p)) % p;
    return ret;
  }
  void operator+=(const long long &other) { num = (num + other) % p; }
  void operator+=(const modint &other) { num = (num + other.num) % p; }
  void operator-=(const long long &other) { num = (num - other + p) % p; }
  void operator-=(const modint &other) { num = (num - other.num + p) % p; }
  void operator*=(const long long &other) { num = (num * other) % p; }
  void operator*=(const modint &other) { num = (num * other.num) % p; }
};
std::ostream &operator<<(std::ostream &os, const modint &x) {
  std::cout << x.num;
  return os;
}

using namespace std;

struct combination {
  vector<modint> li;
  vector<modint> rev;
  combination(int size = 202000) {
    li = vector<modint>(size);
    rev = vector<modint>(size);
    li[0] = 1;
    for (int i = 1; i < size; i++)
      li[i] = li[i - 1] * i;
    rev.back() = modint(1) / li.back();
    for (int i = size - 1; i > 0; i--)
      rev[i - 1] = rev[i] * i;
  }
  modint nCk(int n, int k) {
    if (k <= 0 || n <= k)
      return 1;
    return li[n] * rev[k] * rev[n - k];
  }
} comb(202000);

struct DP {
  modint c;
  int t;
  DP() {
    c = modint(1);
    t = 0;
  }
  void operator+=(const DP &other) {
    t += other.t;
    c *= comb.nCk(t, other.t) * other.c;
  }
  DP operator+(const DP &other) {
    DP ret;
    ret.t = other.t + t;
    ret.c = c * comb.nCk(ret.t, other.t) * other.c;
    return ret;
  }
  DP operator-(const DP &other) {
    DP ret(*this);
    ret.c = ret.c / (comb.nCk(t, other.t) * other.c);
    ret.t -= other.t;
    return ret;
  }
  DP addroot() {
    DP ret(*this);
    ret.t++;
    return ret;
  }
};

void dfs1(int child, vector<vector<int>> &da, vector<DP> &ans, int pare = -1) {
  for (int i = 0; i < da[child].size(); i++) {
    if (da[child][i] == pare)
      continue;
    dfs1(da[child][i], da, ans, child);
    ans[child] += ans[da[child][i]].addroot();
  }
}

void dfs2(int child, vector<vector<int>> &da, vector<DP> &ans,
          const DP &dp = DP(), int pare = -1) {
  if (pare != -1)
    ans[child] += dp;
  int size = da[child].size();
  vector<DP> dpL(size + 1), dpR(size + 1);

  for (int i = 0; i < size; i++) {
    dpL[i + 1] = dpL[i];
    if (da[child][i] == pare)
      dpL[i + 1] += dp;
    else
      dpL[i + 1] += ans[da[child][i]].addroot();
  }

  for (int i = size; i > 0; i--) {
    dpR[i - 1] = dpR[i];
    if (da[child][i - 1] == pare)
      dpR[i - 1] += dp;
    else
      dpR[i - 1] += ans[da[child][i - 1]].addroot();
  }
  for (int i = 0; i < size; i++) {
    int next = da[child][i];
    if (next == pare)
      continue;
    // printf("%d %d\n",child, next);
    dfs2(next, da, ans, (dpL[i] + dpR[i + 1]).addroot(), child);
  }
}

void rooting(vector<vector<int>> &da, vector<DP> &ans) {
  dfs1(0, da, ans);
  dfs2(0, da, ans);
}

int main() {
  int n;
  cin >> n;
  vector<vector<int>> da(n, vector<int>(0));
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    da[a].push_back(b);
    da[b].push_back(a);
  }
  vector<DP> ans(n);
  rooting(da, ans);
  for (int i = 0; i < n; i++)
    cout << ans[i].c << endl;
}