Problem p03367 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define ll long long
#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; i++)
#define DREP(i, a, b) for (int i = (a), _end_ = (b); i >= _end_; i--)
#define EREP(i, a) for (int i = start[(a)]; i; i = e[i].next)
template <class T> inline void chkmax(T &a, T b) {
  if (a < b)
    a = b;
}
template <class T> inline void chkmin(T &a, T b) {
  if (a > b)
    a = b;
}
#define fi first
#define se second
#define mkr(a, b) make_pair(a, b)
inline int read() {
  int sum = 0, p = 1;
  char ch = getchar();
  while (!(('0' <= ch && ch <= '9') || ch == '-'))
    ch = getchar();
  if (ch == '-')
    p = -1, ch = getchar();
  while ('0' <= ch && ch <= '9')
    sum = sum * 10 + ch - 48, ch = getchar();
  return sum * p;
}

const int maxn = 1e5 + 20;
const int mod = 1e9 + 7;

inline void pls(int &a, int b) {
  a += b;
  if (a >= mod)
    a -= mod;
}

#define pii pair<int, int>

inline int power(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      ans = (ll)ans * a % mod;
    b >>= 1;
    a = (ll)a * a % mod;
  }
  return ans;
}

int n, a[maxn], id[maxn];
int inv[maxn];
int S = 1;
int pre[maxn], suf[maxn];

pii Pre[maxn], Suf[maxn];

inline pii operator*(pii a, pii b) {
  return mkr((ll)a.fi * b.fi % mod, a.se + b.se);
}
inline pii operator/(pii a, pii b) {
  return mkr((ll)a.fi * power(b.fi, mod - 2) % mod, a.se - b.se);
}
inline pii Num(int x) { return !x ? mkr(0, 1) : mkr(x, 0); }

inline void init() {
  n = read();
  REP(i, 1, n) a[i] = read(), id[i] = i;
  sort(id + 1, id + n + 1, [](int x, int y) { return a[x] < a[y]; });
  REP(i, 1, n) S = (ll)S * (a[id[i]] - i + 1) % mod;
  if (!S)
    puts("0"), exit(0);
  inv[1] = 1;
  REP(i, 2, n) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
  pre[0] = 1;
  REP(i, 1, n) pre[i] = (ll)pre[i - 1] * (a[id[i]] - i + 1) % mod;
  suf[n + 1] = 1;
  DREP(i, n, 1) suf[i] = (ll)suf[i + 1] * (a[id[i]] - i + 1) % mod;
  Pre[0] = mkr(1, 0);
  REP(i, 1, n) Pre[i] = Pre[i - 1] * Num(a[id[i]] - i + 1);
  Suf[n + 1] = mkr(1, 0);
  DREP(i, n, 1) Suf[i] = Suf[i + 1] * Num(a[id[i]] - i + 1);
}

int s[maxn], vis[maxn], tim;
inline void Add(int x, int d, int Rev) {
  for (x = Rev ? n - x + 1 : x; x <= n; x += x & (-x))
    vis[x] == tim ? (pls(s[x], d), 0) : (vis[x] = tim, s[x] = d);
}
inline int Sum(int x, int Rev) {
  int res = 0;
  for (x = Rev ? n - x + 1 : x; x; x -= x & (-x))
    (vis[x] != tim ? (vis[x] = tim, s[x] = 0) : (pls(res, s[x]), 0));
  return res;
}

int ans;

inline void doing() {
  int de = 1;
  DREP(i, n, 1) {
    int u = id[i];
    int t = Sum(u + 1, 1);
    pls(ans, (ll)pre[i - 1] * de % mod * t % mod *
                 (((ll)(a[u] - i + 1) * (a[u] - i) >> 1) % mod) % mod);
    if (a[u] - i)
      de = (ll)de * (a[u] - i) % mod;
    else
      de = 1, ++tim;
    Add(u, (ll)suf[i + 1] * power(de, mod - 2) % mod, 1);
  }

  ++tim;
  DREP(i, n, 1) {
    int u = id[i];
    int t = Sum(u - 1, 0);
    pls(ans, (ll)t * pre[n] % mod);
    Add(u, 1, 0);
  }
  ++tim;

  de = 1;
  DREP(i, n, 1) {
    int u = id[i];
    int t = Sum(u - 1, 0);
    pls(ans, mod - (ll)pre[i - 1] * de % mod * t % mod *
                       (((ll)(a[u] - i + 1) * (a[u] - i) >> 1) % mod) % mod);
    if (a[u] - i)
      de = (ll)de * (a[u] - i) % mod;
    else
      de = 1, ++tim;
    Add(u, (ll)suf[i + 1] * power(de, mod - 2) % mod, 0);
  }
  printf("%d\n", ans);
}

int main() {
  init();
  doing();
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define ll long long
#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; i++)
#define DREP(i, a, b) for (int i = (a), _end_ = (b); i >= _end_; i--)
#define EREP(i, a) for (int i = start[(a)]; i; i = e[i].next)
template <class T> inline void chkmax(T &a, T b) {
  if (a < b)
    a = b;
}
template <class T> inline void chkmin(T &a, T b) {
  if (a > b)
    a = b;
}
#define fi first
#define se second
#define mkr(a, b) make_pair(a, b)
inline int read() {
  int sum = 0, p = 1;
  char ch = getchar();
  while (!(('0' <= ch && ch <= '9') || ch == '-'))
    ch = getchar();
  if (ch == '-')
    p = -1, ch = getchar();
  while ('0' <= ch && ch <= '9')
    sum = sum * 10 + ch - 48, ch = getchar();
  return sum * p;
}

const int maxn = 2e5 + 20;
const int mod = 1e9 + 7;

inline void pls(int &a, int b) {
  a += b;
  if (a >= mod)
    a -= mod;
}

#define pii pair<int, int>

inline int power(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1)
      ans = (ll)ans * a % mod;
    b >>= 1;
    a = (ll)a * a % mod;
  }
  return ans;
}

int n, a[maxn], id[maxn];
int inv[maxn];
int S = 1;
int pre[maxn], suf[maxn];

pii Pre[maxn], Suf[maxn];

inline pii operator*(pii a, pii b) {
  return mkr((ll)a.fi * b.fi % mod, a.se + b.se);
}
inline pii operator/(pii a, pii b) {
  return mkr((ll)a.fi * power(b.fi, mod - 2) % mod, a.se - b.se);
}
inline pii Num(int x) { return !x ? mkr(0, 1) : mkr(x, 0); }

inline void init() {
  n = read();
  REP(i, 1, n) a[i] = read(), id[i] = i;
  sort(id + 1, id + n + 1, [](int x, int y) { return a[x] < a[y]; });
  REP(i, 1, n) S = (ll)S * (a[id[i]] - i + 1) % mod;
  if (!S)
    puts("0"), exit(0);
  inv[1] = 1;
  REP(i, 2, n) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
  pre[0] = 1;
  REP(i, 1, n) pre[i] = (ll)pre[i - 1] * (a[id[i]] - i + 1) % mod;
  suf[n + 1] = 1;
  DREP(i, n, 1) suf[i] = (ll)suf[i + 1] * (a[id[i]] - i + 1) % mod;
  Pre[0] = mkr(1, 0);
  REP(i, 1, n) Pre[i] = Pre[i - 1] * Num(a[id[i]] - i + 1);
  Suf[n + 1] = mkr(1, 0);
  DREP(i, n, 1) Suf[i] = Suf[i + 1] * Num(a[id[i]] - i + 1);
}

int s[maxn], vis[maxn], tim;
inline void Add(int x, int d, int Rev) {
  for (x = Rev ? n - x + 1 : x; x <= n; x += x & (-x))
    vis[x] == tim ? (pls(s[x], d), 0) : (vis[x] = tim, s[x] = d);
}
inline int Sum(int x, int Rev) {
  int res = 0;
  for (x = Rev ? n - x + 1 : x; x; x -= x & (-x))
    (vis[x] != tim ? (vis[x] = tim, s[x] = 0) : (pls(res, s[x]), 0));
  return res;
}

int ans;

inline void doing() {
  int de = 1;
  DREP(i, n, 1) {
    int u = id[i];
    int t = Sum(u + 1, 1);
    pls(ans, (ll)pre[i - 1] * de % mod * t % mod *
                 (((ll)(a[u] - i + 1) * (a[u] - i) >> 1) % mod) % mod);
    if (a[u] - i)
      de = (ll)de * (a[u] - i) % mod;
    else
      de = 1, ++tim;
    Add(u, (ll)suf[i + 1] * power(de, mod - 2) % mod, 1);
  }

  ++tim;
  DREP(i, n, 1) {
    int u = id[i];
    int t = Sum(u - 1, 0);
    pls(ans, (ll)t * pre[n] % mod);
    Add(u, 1, 0);
  }
  ++tim;

  de = 1;
  DREP(i, n, 1) {
    int u = id[i];
    int t = Sum(u - 1, 0);
    pls(ans, mod - (ll)pre[i - 1] * de % mod * t % mod *
                       (((ll)(a[u] - i + 1) * (a[u] - i) >> 1) % mod) % mod);
    if (a[u] - i)
      de = (ll)de * (a[u] - i) % mod;
    else
      de = 1, ++tim;
    Add(u, (ll)suf[i + 1] * power(de, mod - 2) % mod, 0);
  }
  printf("%d\n", ans);
}

int main() {
  init();
  doing();
  return 0;
}