Problem p03367 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

const int mod = 1000000007, iv2 = (mod + 1 >> 1);
int n, cnt, nw, ans1, ans2, pre[200010];
struct node {
  int v, p;
} a[200010];
struct Node {
  int v1, v2, l, r, laz;
} t[200010];

bool cmp(node a, node b) { return a.v < b.v; }
int add(int x, int y) { return x + y >= mod ? x + y - mod : x + y; }
Node operator+(Node a, Node b) {
  return (Node){a.v1 + b.v1, add(a.v2, b.v2), a.l, b.r, 1};
}

void build(int i, int l, int r) {
  t[i].l = l, t[i].r = r, t[i].laz = 1, t[i].v1 = t[i].v2 = 0;
  if (l == r)
    return;
  int mid = (l + r) >> 1;
  build(i << 1, l, mid), build(i << 1 | 1, mid + 1, r);
}

void pushdown(int i) {
  if (t[i].laz == 1)
    return;
  t[i << 1].v2 = 1ll * t[i << 1].v2 * t[i].laz % mod,
         t[i << 1].laz = 1ll * t[i].laz * t[i << 1].laz % mod;
  t[i << 1 | 1].v2 = 1ll * t[i << 1 | 1].v2 * t[i].laz % mod,
             t[i << 1 | 1].laz = 1ll * t[i].laz * t[i << 1 | 1].laz % mod;
  t[i].laz = 1;
}

void add(int i, int x, int v2) {
  if (t[i].l == t[i].r) {
    t[i].v1++, t[i].v2 = add(t[i].v2, v2);
    return;
  }
  pushdown(i);
  int mid = (t[i].l + t[i].r) >> 1;
  add(i << 1 | (x > mid), x, v2), t[i] = t[i << 1] + t[i << 1 | 1];
}

Node query(int i, int l, int r) {
  if (t[i].l == l && t[i].r == r)
    return t[i];
  pushdown(i);
  int mid = (t[i].l + t[i].r) >> 1;
  if (r <= mid)
    return query(i << 1, l, r);
  if (l > mid)
    return query(i << 1 | 1, l, r);
  return query(i << 1, l, mid) + query(i << 1 | 1, mid + 1, r);
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i].v), a[i].p = i;
  sort(a + 1, a + 1 + n, cmp), cnt = 0, nw = 1, build(1, 1, n), ans1 = ans2 = 0,
                               pre[0] = 1;
  for (int i = 1; i <= n; i++)
    pre[i] = 1ll * pre[i - 1] * (a[i].v - i + 1) % mod;
  for (int i = n; i; i--) {
    Node L = query(1, 1, a[i].p), R = query(1, a[i].p, n);
    ans1 = (ans1 + 1ll * L.v2 * (a[i].v - i + mod) % mod *
                       (a[i].v - i + 1 + mod) % mod * pre[i - 1]) %
           mod;
    ans2 = (ans2 + 1ll * R.v2 * (a[i].v - i + mod) % mod *
                       (a[i].v - i + 1 + mod) % mod * pre[i - 1]) %
           mod;
    t[1].laz = 1ll * t[1].laz * (a[i].v - i + mod) % mod,
    t[1].v2 = 1ll * t[1].v2 * (a[i].v - i + mod) % mod;
    cnt = add(cnt, L.v1), add(1, a[i].p, nw),
    nw = 1ll * nw * (a[i].v - i + 1 + mod) % mod;
  }
  ans1 = 1ll * ans1 * iv2 % mod, ans2 = 1ll * ans2 * iv2 % mod;
  ans2 = (ans2 + 1ll * cnt * pre[n] - ans1 + mod) % mod;
  return printf("%d\n", ans2), 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int mod = 1000000007, iv2 = (mod + 1 >> 1);
int n, cnt, nw, ans1, ans2, pre[200010];
struct node {
  int v, p;
} a[200010];
struct Node {
  int v1, v2, l, r, laz;
} t[800010];

bool cmp(node a, node b) { return a.v < b.v; }
int add(int x, int y) { return x + y >= mod ? x + y - mod : x + y; }
Node operator+(Node a, Node b) {
  return (Node){a.v1 + b.v1, add(a.v2, b.v2), a.l, b.r, 1};
}

void build(int i, int l, int r) {
  t[i].l = l, t[i].r = r, t[i].laz = 1, t[i].v1 = t[i].v2 = 0;
  if (l == r)
    return;
  int mid = (l + r) >> 1;
  build(i << 1, l, mid), build(i << 1 | 1, mid + 1, r);
}

void pushdown(int i) {
  if (t[i].laz == 1)
    return;
  t[i << 1].v2 = 1ll * t[i << 1].v2 * t[i].laz % mod,
         t[i << 1].laz = 1ll * t[i].laz * t[i << 1].laz % mod;
  t[i << 1 | 1].v2 = 1ll * t[i << 1 | 1].v2 * t[i].laz % mod,
             t[i << 1 | 1].laz = 1ll * t[i].laz * t[i << 1 | 1].laz % mod;
  t[i].laz = 1;
}

void add(int i, int x, int v2) {
  if (t[i].l == t[i].r) {
    t[i].v1++, t[i].v2 = add(t[i].v2, v2);
    return;
  }
  pushdown(i);
  int mid = (t[i].l + t[i].r) >> 1;
  add(i << 1 | (x > mid), x, v2), t[i] = t[i << 1] + t[i << 1 | 1];
}

Node query(int i, int l, int r) {
  if (t[i].l == l && t[i].r == r)
    return t[i];
  pushdown(i);
  int mid = (t[i].l + t[i].r) >> 1;
  if (r <= mid)
    return query(i << 1, l, r);
  if (l > mid)
    return query(i << 1 | 1, l, r);
  return query(i << 1, l, mid) + query(i << 1 | 1, mid + 1, r);
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i].v), a[i].p = i;
  sort(a + 1, a + 1 + n, cmp), cnt = 0, nw = 1, build(1, 1, n), ans1 = ans2 = 0,
                               pre[0] = 1;
  for (int i = 1; i <= n; i++)
    pre[i] = 1ll * pre[i - 1] * (a[i].v - i + 1) % mod;
  for (int i = n; i; i--) {
    Node L = query(1, 1, a[i].p), R = query(1, a[i].p, n);
    ans1 = (ans1 + 1ll * L.v2 * (a[i].v - i + mod) % mod *
                       (a[i].v - i + 1 + mod) % mod * pre[i - 1]) %
           mod;
    ans2 = (ans2 + 1ll * R.v2 * (a[i].v - i + mod) % mod *
                       (a[i].v - i + 1 + mod) % mod * pre[i - 1]) %
           mod;
    t[1].laz = 1ll * t[1].laz * (a[i].v - i + mod) % mod,
    t[1].v2 = 1ll * t[1].v2 * (a[i].v - i + mod) % mod;
    cnt = add(cnt, L.v1), add(1, a[i].p, nw),
    nw = 1ll * nw * (a[i].v - i + 1 + mod) % mod;
  }
  ans1 = 1ll * ans1 * iv2 % mod, ans2 = 1ll * ans2 * iv2 % mod;
  ans2 = (ans2 + 1ll * cnt * pre[n] - ans1 + mod) % mod;
  return printf("%d\n", ans2), 0;
}