Problem p03094 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 1000000 + 117;
const int MM = 1000000 + 117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("a.in", "r", stdin);
  // freopen("a.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

LL n;
const int mod = 1e9 + 7;
LL ksm(LL a, LL b) {
  LL ret = 1;
  for (; b; b >>= 1, a = a * a % mod)
    if (b & 1)
      ret = ret * a % mod;
  return ret;
}
LL p[NN] = {};
LL fact[2 * NN] = {};
LL rev[2 * NN] = {};
LL comp(int n, int m) { return fact[n] * rev[m] % mod * rev[n - m] % mod; }
LL prefact(int n) {
  fact[0] = 1;
  for (int i = 1; i <= n; ++i)
    fact[i] = fact[i - 1] * i % mod;
  rev[n] = ksm(fact[n], mod - 2);
  for (int i = n; i >= 1; --i)
    rev[i - 1] = rev[i] * i % mod;
}
int main() {
  open();
  n = read();
  prefact(n);
  LL ans = 0;
  LL di = ksm(3, n - 1);
  di = ksm(di, mod - 2);
  LL len = ksm(3 * n, mod - 2);
  for (int i = 2; i <= n + 1; ++i) {
    if (i == 2)
      p[i] = di;
    else
      p[i] = (p[i - 1] + p[i - 2] * 2) % mod;
    LL res = p[i] * comp(n, i - 1) % mod;
    res = res * len % mod * fact[i - 2] % mod * rev[i - 1] % mod;
    ans = (ans + res) % mod;
  }
  printf("%lld\n", ans);
  close();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 1000000 + 117;
const int MM = 1000000 + 117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("a.in", "r", stdin);
  // freopen("a.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

LL n;
const int mod = 1e9 + 7;
LL ksm(LL a, LL b) {
  LL ret = 1;
  for (; b; b >>= 1, a = a * a % mod)
    if (b & 1)
      ret = ret * a % mod;
  return ret;
}
LL p[NN] = {};
LL fact[2 * NN] = {};
LL rev[2 * NN] = {};
LL comp(int n, int m) { return fact[n] * rev[m] % mod * rev[n - m] % mod; }
LL prefact(int n) {
  fact[0] = 1;
  for (int i = 1; i <= n; ++i)
    fact[i] = fact[i - 1] * i % mod;
  rev[n] = ksm(fact[n], mod - 2);
  for (int i = n; i >= 1; --i)
    rev[i - 1] = rev[i] * i % mod;
}
int main() {
  // open();
  n = read();
  prefact(n);
  LL ans = 0;
  LL di = ksm(3, n - 1);
  di = ksm(di, mod - 2);
  LL len = ksm(3 * n, mod - 2);
  for (int i = 2; i <= n + 1; ++i) {
    if (i == 2)
      p[i] = di;
    else
      p[i] = (p[i - 1] + p[i - 2] * 2) % mod;
    LL res = p[i] * comp(n, i - 1) % mod;
    res = res * len % mod * fact[i - 2] % mod * rev[i - 1] % mod;
    ans = (ans + res) % mod;
  }
  printf("%lld\n", ans);
  close();
  return 0;
}