Problem p03367 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N = 4e5 + 10;
const int mod = 1e9 + 7;
const int inv2 = 5e8 + 4;
typedef pair<int, int> pii;
int gi() {
  int x = 0, o = 1;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-')
    ch = getchar();
  if (ch == '-')
    o = -1, ch = getchar();
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  return x * o;
}
int n, a[N], cnt[N];
vector<int> V[N];
int qpow(int a, int b) {
  int ret = 1;
  while (b) {
    if (b & 1)
      ret = 1ll * ret * a % mod;
    a = 1ll * a * a % mod;
    b >>= 1;
  }
  return ret;
}
pii operator+(pii a, pii b) { return mp((a.fi + b.fi) % mod, a.se + b.se); }
int tag[N << 2];
pii tr[N << 2];
#define ls (o << 1)
#define rs (o << 1 | 1)
void build(int o, int l, int r) {
  tag[o] = 1;
  if (l == r)
    return;
  int mid = (l + r) >> 1;
  build(ls, l, mid);
  build(rs, mid + 1, r);
}
void modify(int o, int v) {
  tr[o].fi = 1ll * tr[o].fi * v % mod;
  tag[o] = 1ll * tag[o] * v % mod;
}
void down(int o) {
  if (tag[o] == 1)
    return;
  modify(ls, tag[o]);
  modify(rs, tag[o]);
  tag[o] = 1;
}
void update(int o, int l, int r, int p, int v) {
  if (l == r) {
    tr[o] = mp(v, 1);
    return;
  }
  down(o);
  int mid = (l + r) >> 1;
  if (p <= mid)
    update(ls, l, mid, p, v);
  else
    update(rs, mid + 1, r, p, v);
  tr[o] = tr[ls] + tr[rs];
}
pii query(int o, int l, int r, int L, int R) {
  if (L <= l && r <= R)
    return tr[o];
  down(o);
  int mid = (l + r) >> 1;
  pii ret = mp(0, 0);
  if (L <= mid)
    ret = ret + query(ls, l, mid, L, R);
  if (R > mid)
    ret = ret + query(rs, mid + 1, r, L, R);
  return ret;
}
int main() {
#ifndef ONLINE_JUDGE
  freopen("at3956.in", "r", stdin);
  freopen("at3956.out", "w", stdout);
#endif
  cin >> n;
  for (int i = 1; i <= n; i++)
    a[i] = gi(), cnt[a[i]]++, V[a[i]].pb(i);
  for (int i = n - 1; i; i--)
    cnt[i] += cnt[i + 1];
  int mul = 1;
  for (int i = 1; i <= n; i++) {
    if (cnt[i] <= n - i)
      return puts("0"), 0;
    mul = 1ll * mul * (cnt[i] - (n - i)) % mod;
  }
  build(1, 1, n);
  int ans = 0;
  for (int j = n; j; j--) {
    for (int i : V[j]) {
      pii ret = query(1, 1, n, i, n);
      ans = (ans + 1ll * ret.fi * inv2 % mod);
      ret = query(1, 1, n, 1, i);
      ans = ((ans + 1ll * ret.se * mul % mod) % mod -
             1ll * ret.fi * inv2 % mod + mod) %
            mod;
    }
    int sz = V[j].size();
    ans = (ans +
           1ll * sz * (sz - 1) % mod * inv2 % mod * mul % mod * inv2 % mod) %
          mod;
    for (int i : V[j])
      update(1, 1, n, i, mul);
    int tmp =
        1ll * (cnt[j] - 1 - (n - j)) * qpow(cnt[j] - (n - j), mod - 2) % mod;
    modify(1, tmp);
  }
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N = 4e5 + 10;
const int mod = 1e9 + 7;
const int inv2 = 5e8 + 4;
typedef pair<int, int> pii;
int gi() {
  int x = 0, o = 1;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-')
    ch = getchar();
  if (ch == '-')
    o = -1, ch = getchar();
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  return x * o;
}
int n, a[N], cnt[N];
vector<int> V[N];
int qpow(int a, int b) {
  int ret = 1;
  while (b) {
    if (b & 1)
      ret = 1ll * ret * a % mod;
    a = 1ll * a * a % mod;
    b >>= 1;
  }
  return ret;
}
pii operator+(pii a, pii b) { return mp((a.fi + b.fi) % mod, a.se + b.se); }
int tag[N << 2];
pii tr[N << 2];
#define ls (o << 1)
#define rs (o << 1 | 1)
void build(int o, int l, int r) {
  tag[o] = 1;
  if (l == r)
    return;
  int mid = (l + r) >> 1;
  build(ls, l, mid);
  build(rs, mid + 1, r);
}
void modify(int o, int v) {
  tr[o].fi = 1ll * tr[o].fi * v % mod;
  tag[o] = 1ll * tag[o] * v % mod;
}
void down(int o) {
  if (tag[o] == 1)
    return;
  modify(ls, tag[o]);
  modify(rs, tag[o]);
  tag[o] = 1;
}
void update(int o, int l, int r, int p, int v) {
  if (l == r) {
    tr[o] = mp(v, 1);
    return;
  }
  down(o);
  int mid = (l + r) >> 1;
  if (p <= mid)
    update(ls, l, mid, p, v);
  else
    update(rs, mid + 1, r, p, v);
  tr[o] = tr[ls] + tr[rs];
}
pii query(int o, int l, int r, int L, int R) {
  if (L <= l && r <= R)
    return tr[o];
  down(o);
  int mid = (l + r) >> 1;
  pii ret = mp(0, 0);
  if (L <= mid)
    ret = ret + query(ls, l, mid, L, R);
  if (R > mid)
    ret = ret + query(rs, mid + 1, r, L, R);
  return ret;
}
int main() {
  cin >> n;
  for (int i = 1; i <= n; i++)
    a[i] = gi(), cnt[a[i]]++, V[a[i]].pb(i);
  for (int i = n - 1; i; i--)
    cnt[i] += cnt[i + 1];
  int mul = 1;
  for (int i = 1; i <= n; i++) {
    if (cnt[i] <= n - i)
      return puts("0"), 0;
    mul = 1ll * mul * (cnt[i] - (n - i)) % mod;
  }
  build(1, 1, n);
  int ans = 0;
  for (int j = n; j; j--) {
    for (int i : V[j]) {
      pii ret = query(1, 1, n, i, n);
      ans = (ans + 1ll * ret.fi * inv2 % mod);
      ret = query(1, 1, n, 1, i);
      ans = ((ans + 1ll * ret.se * mul % mod) % mod -
             1ll * ret.fi * inv2 % mod + mod) %
            mod;
    }
    int sz = V[j].size();
    ans = (ans +
           1ll * sz * (sz - 1) % mod * inv2 % mod * mul % mod * inv2 % mod) %
          mod;
    for (int i : V[j])
      update(1, 1, n, i, mul);
    int tmp =
        1ll * (cnt[j] - 1 - (n - j)) * qpow(cnt[j] - (n - j), mod - 2) % mod;
    modify(1, tmp);
  }
  printf("%d\n", ans);
  return 0;
}