Problem p02919 (C++)

Buggy submission (status: Runtime Error):
#include "bits/stdc++.h"

using namespace std;

#define ll long long int
#define endl '\n'

static const int maxn = 2e5 + 5;

struct Seg {
  int fmax, smax;
  Seg(int fmax = 0, int smax = 0) : fmax(fmax), smax(smax) {}

  void assignLeaf(int num) {
    fmax = num;
    smax = 0;
  }
  void marge(const Seg &lchild, const Seg &rchild) {
    fmax = max(lchild.fmax, rchild.fmax);
    smax = max({min(lchild.fmax, rchild.fmax), lchild.smax, rchild.smax});
  }
} Tree[maxn * 4];

void build(int node, int a, int b) {
  if (a == b)
    return void(Tree[node] = Seg());
  int lchild = node * 2;
  int rchild = lchild + 1;
  int mid = (a + b) / 2;
  build(lchild, a, mid);
  build(rchild, mid + 1, b);
  Tree[node].marge(Tree[lchild], Tree[rchild]);
}

void update(int node, int a, int b, int pos, int val) {
  if (a > pos or b < pos)
    return;
  if (a >= pos and b <= pos)
    return void(Tree[node].assignLeaf(val));
  int lchild = node * 2;
  int rchild = lchild + 1;
  int mid = (a + b) / 2;
  update(lchild, a, mid, pos, val);
  update(rchild, mid + 1, b, pos, val);
  Tree[node].marge(Tree[lchild], Tree[rchild]);
}

Seg query(int node, int a, int b, int i, int j) {
  if (a > j or b < i)
    return Seg();
  if (a >= i and b <= j)
    return Tree[node];
  int lchild = node * 2;
  int rchild = lchild + 1;
  int mid = (a + b) / 2;
  Seg p = query(lchild, a, mid, i, j);
  Seg q = query(rchild, mid + 1, b, i, j);
  Seg res;
  res.marge(p, q);
  return res;
}

ll ans;

void solve(vector<int> &vec) {
  int n = vec.size() - 1;
  vector<Seg> LEFT(n + 1);
  build(1, 1, n);
  for (int i = 1; i <= n; i++) {
    Seg pos = query(1, 1, n, vec[i] + 1, n);
    LEFT[i] = pos;
    ans += 1LL * vec[i] * (LEFT[i].fmax - LEFT[i].smax);
    //            cerr << "LEFT " << i << " " << LEFT[i].fmax << " " <<
    //            LEFT[i].smax <<  " " << 1LL * vec[i] * (LEFT[i].fmax -
    //            LEFT[i].smax) << endl;
    update(1, 1, n, vec[i], i);
  }
  reverse(vec.begin() + 1, vec.end());
  vector<Seg> RIGHT(n + 1);
  build(1, 1, n);
  for (int i = 1; i <= n; i++) {
    Seg pos = query(1, 1, n, vec[i] + 1, n);
    RIGHT[i] = pos;
    ans += 1LL * vec[i] * (RIGHT[i].fmax - RIGHT[i].smax);
    //            cerr << "RIGHT " << i << " " << RIGHT[i].fmax << " " <<
    //            RIGHT[i].smax <<  " " << 1LL * vec[i] * (RIGHT[i].fmax -
    //            RIGHT[i].smax) << endl;
    int j = n - i + 1;
    if (j > LEFT[j].fmax)
      ans += 1LL * vec[i] * (j - LEFT[j].fmax - 1) *
             (RIGHT[i].fmax - RIGHT[i].smax);
    if (i > RIGHT[i].fmax)
      ans += 1LL * vec[i] * (i - RIGHT[i].fmax - 1) *
             (LEFT[j].fmax - LEFT[j].smax);
    update(1, 1, n, vec[i], i);
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE

  int n;
  cin >> n;
  vector<int> vec(n + 1);
  for (int i = 1; i <= n; i++)
    cin >> vec[i];
  solve(vec);
  cout << ans << endl;
}


Fixed submission:
#include "bits/stdc++.h"

using namespace std;

#define ll long long int
#define endl '\n'

static const int maxn = 2e5 + 5;

struct Seg {
  int fmax, smax;
  Seg(int fmax = 0, int smax = 0) : fmax(fmax), smax(smax) {}

  void assignLeaf(int num) {
    fmax = num;
    smax = 0;
  }
  void marge(const Seg &lchild, const Seg &rchild) {
    fmax = max(lchild.fmax, rchild.fmax);
    smax = max({min(lchild.fmax, rchild.fmax), lchild.smax, rchild.smax});
  }
} Tree[maxn * 4];

void build(int node, int a, int b) {
  if (a == b)
    return void(Tree[node] = Seg());
  int lchild = node * 2;
  int rchild = lchild + 1;
  int mid = (a + b) / 2;
  build(lchild, a, mid);
  build(rchild, mid + 1, b);
  Tree[node].marge(Tree[lchild], Tree[rchild]);
}

void update(int node, int a, int b, int pos, int val) {
  if (a > pos or b < pos)
    return;
  if (a >= pos and b <= pos)
    return void(Tree[node].assignLeaf(val));
  int lchild = node * 2;
  int rchild = lchild + 1;
  int mid = (a + b) / 2;
  update(lchild, a, mid, pos, val);
  update(rchild, mid + 1, b, pos, val);
  Tree[node].marge(Tree[lchild], Tree[rchild]);
}

Seg query(int node, int a, int b, int i, int j) {
  if (a > j or b < i)
    return Seg();
  if (a >= i and b <= j)
    return Tree[node];
  int lchild = node * 2;
  int rchild = lchild + 1;
  int mid = (a + b) / 2;
  Seg p = query(lchild, a, mid, i, j);
  Seg q = query(rchild, mid + 1, b, i, j);
  Seg res;
  res.marge(p, q);
  return res;
}

ll ans;

void solve(vector<int> &vec) {
  int n = vec.size() - 1;
  vector<Seg> LEFT(n + 1);
  build(1, 1, n);
  for (int i = 1; i <= n; i++) {
    Seg pos = query(1, 1, n, vec[i] + 1, n);
    LEFT[i] = pos;
    ans += 1LL * vec[i] * (LEFT[i].fmax - LEFT[i].smax);
    //            cerr << "LEFT " << i << " " << LEFT[i].fmax << " " <<
    //            LEFT[i].smax <<  " " << 1LL * vec[i] * (LEFT[i].fmax -
    //            LEFT[i].smax) << endl;
    update(1, 1, n, vec[i], i);
  }
  reverse(vec.begin() + 1, vec.end());
  vector<Seg> RIGHT(n + 1);
  build(1, 1, n);
  for (int i = 1; i <= n; i++) {
    Seg pos = query(1, 1, n, vec[i] + 1, n);
    RIGHT[i] = pos;
    ans += 1LL * vec[i] * (RIGHT[i].fmax - RIGHT[i].smax);
    //            cerr << "RIGHT " << i << " " << RIGHT[i].fmax << " " <<
    //            RIGHT[i].smax <<  " " << 1LL * vec[i] * (RIGHT[i].fmax -
    //            RIGHT[i].smax) << endl;
    int j = n - i + 1;
    if (j > LEFT[j].fmax)
      ans += 1LL * vec[i] * (j - LEFT[j].fmax - 1) *
             (RIGHT[i].fmax - RIGHT[i].smax);
    if (i > RIGHT[i].fmax)
      ans += 1LL * vec[i] * (i - RIGHT[i].fmax - 1) *
             (LEFT[j].fmax - LEFT[j].smax);
    update(1, 1, n, vec[i], i);
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int n;
  cin >> n;
  vector<int> vec(n + 1);
  for (int i = 1; i <= n; i++)
    cin >> vec[i];
  solve(vec);
  cout << ans << endl;
}