Problem p03365 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <iostream>
using namespace std;

long long modpow(long long a, long long b, long long m) {
  long long p = 1, q = a;
  for (int i = 0; i < 40; i++) {
    if ((b / (1LL << i)) % 2 == 1) {
      p *= q;
      p %= m;
    }
    q *= q;
    q %= m;
  }
  return p;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % m;
}

long long N, fact[1000009], factinv[1000009], inv[1000009], mod = 1000000007;
const int MAX_N = 1000006;

void init() {
  fact[0] = 1;
  for (int i = 1; i <= MAX_N; i++) {
    fact[i] = 1LL * fact[i - 1] * i;
    fact[i] %= mod;
  }
  for (int i = 0; i <= MAX_N; i++)
    factinv[i] = Div(1, fact[i], mod);
  for (int i = 1; i <= MAX_N; i++)
    inv[i] = Div(1, i, mod);
}
long long ncr(long long n, long long r) {
  if (r < 0 || n < r)
    return 0;
  long long R = factinv[r] * factinv[n - r];
  R %= mod;
  return (R * fact[n]) % mod;
}

int main() {
  cin >> N;
  if (N == 2) {
    cout << "1" << endl;
    return 0;
  }
  if (N == 3) {
    cout << "4" << endl;
    return 0;
  }
  if (N == 4) {
    cout << "16" << endl;
    return 0;
  }

  long long sum = 0;
  init();

  for (int i = 3; i <= N; i++) {
    long long E = 2 * (i - 1) - (N - 2);
    long long V = ncr(i - 1, E);
    long long U = E * (E - 1);
    U %= mod;
    U *= inv[i - 1];
    U %= mod;
    U *= inv[i - 2];
    U %= mod;
    U = (mod + 1 - U);
    U %= mod;
    U *= (i - 2);
    U %= mod;
    U += 2;
    U %= mod;

    V *= U;
    V %= mod;
    V *= (fact[i - 1] * fact[N - 1 - i]) % mod;
    V %= mod;
    sum += (V * i) % mod;
    sum %= mod;
  }
  cout << sum << endl;
  return 0;
}

Fixed submission:
#include <iostream>
using namespace std;

long long modpow(long long a, long long b, long long m) {
  long long p = 1, q = a;
  for (int i = 0; i < 34; i++) {
    if ((b / (1LL << i)) % 2 == 1) {
      p *= q;
      p %= m;
    }
    q *= q;
    q %= m;
  }
  return p;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % m;
}

long long N, fact[1000009], factinv[1000009], inv[1000009], mod = 1000000007;
const int MAX_N = 1000006;

void init() {
  fact[0] = 1;
  for (int i = 1; i <= MAX_N; i++) {
    fact[i] = 1LL * fact[i - 1] * i;
    fact[i] %= mod;
  }
  for (int i = 0; i <= MAX_N; i++)
    factinv[i] = Div(1, fact[i], mod);
  for (int i = 1; i <= MAX_N; i++)
    inv[i] = Div(1, i, mod);
}
long long ncr(long long n, long long r) {
  if (r < 0 || n < r)
    return 0;
  long long R = factinv[r] * factinv[n - r];
  R %= mod;
  return (R * fact[n]) % mod;
}

int main() {
  cin >> N;
  if (N == 2) {
    cout << "1" << endl;
    return 0;
  }
  if (N == 3) {
    cout << "4" << endl;
    return 0;
  }
  if (N == 4) {
    cout << "16" << endl;
    return 0;
  }

  long long sum = 0;
  init();

  for (int i = 3; i <= N; i++) {
    long long E = 2 * (i - 1) - (N - 2);
    long long V = ncr(i - 1, E);
    long long U = E * (E - 1);
    U %= mod;
    U *= inv[i - 1];
    U %= mod;
    U *= inv[i - 2];
    U %= mod;
    U = (mod + 1 - U);
    U %= mod;
    U *= (i - 2);
    U %= mod;
    U += 2;
    U %= mod;

    V *= U;
    V %= mod;
    V *= (fact[i - 1] * fact[N - 1 - i]) % mod;
    V %= mod;
    sum += (V * i) % mod;
    sum %= mod;
  }
  cout << sum << endl;
  return 0;
}