Problem p03987 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define INF 2e9
#define ALL(v) v.begin(), v.end()
#define TM_T template <class T>
using namespace std;
typedef long long ll;
TM_T T inp() {
  T it;
  cin >> it;
  return it;
}

ll N;
vector<ll> li;
vector<ll> bs;

const int MAX = 300000;
struct segtree {
  int N, dat[2 * MAX];
  segtree() {}
  segtree(int n) {
    N = 1;
    while (N < n)
      N *= 2;
    for (int i = 0; i < 2 * N - 1; i++)
      dat[i] = INF;
  }
  // update k th element
  void update(int k, int a) {
    k += N - 1; // leaf
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  // min [a, b)
  int query(int a, int b) { return query(a, b, 0, 0, N); }
  int query(int a, int b, int k, int l, int r) {
    if (r <= a or b <= l)
      return INF;
    if (a <= l and r <= b)
      return dat[k];
    int m = (l + r) / 2;
    return min(query(a, b, k * 2 + 1, l, m), query(a, b, k * 2 + 2, m, r));
  }
};

struct segtree seg;

int input() {
  cin >> N;
  REP(i, N) li.push_back(inp<ll>());
}

ll div(ll n, ll l, ll r) {
  // cout << n << "," << l << "," << r << "," << bs[n] << endl;

  ll su = 0;
  su += (bs[n] - l + 1) * (r - bs[n] + 1) * n;
  if (l < bs[n])
    su += div(seg.query(l, bs[n] - 1 + 1), l, bs[n] - 1);
  if (bs[n] < r)
    su += div(seg.query(bs[n] + 1, r + 1), bs[n] + 1, r);
  return su;
}

int main() {

  input();
  seg.N = N;
  REP(i, N) seg.update(i, li[i]);

  REP(i, N + 1) bs.push_back(-1);
  REP(i, N) bs[li[i]] = i;
  ll ret = div(1, 0, N - 1);

  cout << ret << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define INF 2e9
#define ALL(v) v.begin(), v.end()
#define TM_T template <class T>
using namespace std;
typedef long long ll;
TM_T T inp() {
  T it;
  cin >> it;
  return it;
}

ll N;
vector<ll> li;
vector<ll> bs;

const int MAX = 300000;
struct segtree {
  int N, dat[2 * MAX];
  segtree() {}
  segtree(int n) {
    N = 1;
    while (N < n)
      N *= 2;
    for (int i = 0; i < 2 * N - 1; i++)
      dat[i] = INF;
  }
  // update k th element
  void update(int k, int a) {
    k += N - 1; // leaf
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  // min [a, b)
  int query(int a, int b) { return query(a, b, 0, 0, N); }
  int query(int a, int b, int k, int l, int r) {
    if (r <= a or b <= l)
      return INF;
    if (a <= l and r <= b)
      return dat[k];
    int m = (l + r) / 2;
    return min(query(a, b, k * 2 + 1, l, m), query(a, b, k * 2 + 2, m, r));
  }
};

struct segtree seg;

int input() {
  cin >> N;
  REP(i, N) li.push_back(inp<ll>());
}

ll div(ll n, ll l, ll r) {
  // cout << n << "," << l << "," << r << "," << bs[n] << endl;

  ll su = 0;
  su += (bs[n] - l + 1) * (r - bs[n] + 1) * n;
  if (l < bs[n])
    su += div(seg.query(l, bs[n] - 1 + 1), l, bs[n] - 1);
  if (bs[n] < r)
    su += div(seg.query(bs[n] + 1, r + 1), bs[n] + 1, r);
  return su;
}

int main() {

  input();
  seg = segtree(N);
  REP(i, N) seg.update(i, li[i]);

  REP(i, N + 1) bs.push_back(-1);
  REP(i, N) bs[li[i]] = i;
  ll ret = div(1, 0, N - 1);

  cout << ret << endl;
}