Problem p02919 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using Cache = pair<long long, pair<long long, long long>>;

const bool DEBUG = false;

Cache cache = make_pair(-1, make_pair(-1, 1));

tuple<long long, long long, long long, long long>
get_anchors(long long i, const vector<long long> &P) {
  long long outer_left_anchor, inner_left_anchor, inner_right_anchor,
      outer_right_anchor;
  long long anchor;

  anchor = (P[i] > cache.first) ? min(cache.second.first, i - 1) : i - 1;
  while ((anchor >= 0) && P[anchor] < P[i])
    anchor--;
  inner_left_anchor = anchor;
  if (anchor == -1) {
    outer_left_anchor = -1;
  } else {
    anchor--;
    while ((anchor >= 0) && P[anchor] < P[i])
      anchor--;
    outer_left_anchor = anchor;
  }

  anchor = (P[i] > cache.first) ? max(cache.second.second, i + 1) : i + 1;
  while ((anchor < P.size()) && P[anchor] < P[i])
    anchor++;
  inner_right_anchor = anchor;
  if (anchor == P.size()) {
    outer_right_anchor = P.size();
  } else {
    anchor++;
    while ((anchor < P.size()) && P[anchor] < P[i])
      anchor++;
    outer_right_anchor = anchor;
  }

  if (P[i] > cache.first) {
    if (DEBUG)
      cout << "cache hit at: (" << inner_left_anchor << ", " << i << ", "
           << inner_right_anchor << ")" << endl;
    cache.first = P[i];
    cache.second.first = inner_left_anchor;
    cache.second.second = inner_right_anchor;
  }

  return forward_as_tuple(outer_left_anchor, inner_left_anchor,
                          inner_right_anchor, outer_right_anchor);
}

int main(int argc, char const *argv[]) {
  long long N;
  cin >> N;
  vector<long long> P(N);
  for (size_t i = 0; i < N; i++)
    cin >> P[i];

  long long total = 0;
  long long outer_left_anchor, inner_left_anchor, inner_right_anchor,
      outer_right_anchor;
  for (size_t i = 0; i < N; i++) {
    tie(outer_left_anchor, inner_left_anchor, inner_right_anchor,
        outer_right_anchor) = get_anchors(i, P);

    total +=
        P[i] *
        (((i - inner_left_anchor) * (outer_right_anchor - inner_right_anchor)) +
         ((inner_left_anchor - outer_left_anchor) * (inner_right_anchor - i)));

    if (DEBUG)
      cout << outer_left_anchor << ", " << inner_left_anchor << ", " << i
           << ", " << inner_right_anchor << ", " << outer_right_anchor << endl;
  }

  cout << total << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using Cache = pair<long long, pair<long long, long long>>;

const bool DEBUG = false;

Cache cache = make_pair(-1, make_pair(-1, 1));

tuple<long long, long long, long long, long long>
get_anchors(long long i, const vector<long long> &P) {
  long long outer_left_anchor, inner_left_anchor, inner_right_anchor,
      outer_right_anchor;
  long long anchor;

  anchor = (P[i] > cache.first) ? min(cache.second.first, i - 1) : i - 1;
  while ((anchor >= 0) && P[anchor] < P[i])
    anchor--;
  inner_left_anchor = anchor;
  if (anchor == -1) {
    outer_left_anchor = -1;
  } else {
    anchor--;
    while ((anchor >= 0) && P[anchor] < P[i])
      anchor--;
    outer_left_anchor = anchor;
  }

  anchor = (P[i] > cache.first) ? max(cache.second.second, i + 1) : i + 1;
  while ((anchor < P.size()) && P[anchor] < P[i])
    anchor++;
  inner_right_anchor = anchor;
  if (anchor == P.size()) {
    outer_right_anchor = P.size();
  } else {
    anchor++;
    while ((anchor < P.size()) && P[anchor] < P[i])
      anchor++;
    outer_right_anchor = anchor;
  }

  if (P[i] > cache.first) {
    if (DEBUG)
      cout << "cache hit at: (" << inner_left_anchor << ", " << i << ", "
           << inner_right_anchor << ")" << endl;
    cache.first = P[i];
    cache.second.first = inner_left_anchor;
    cache.second.second = inner_right_anchor;
  }

  return forward_as_tuple(outer_left_anchor, inner_left_anchor,
                          inner_right_anchor, outer_right_anchor);
}

int main(int argc, char const *argv[]) {
  long long N;
  cin >> N;
  vector<long long> P(N);
  for (size_t i = 0; i < N; i++)
    cin >> P[i];

  size_t max_index = distance(P.begin(), max_element(P.begin(), P.end()));
  if (max_index <= P.size() / 2)
    reverse(P.begin(), P.end());

  long long total = 0;
  long long outer_left_anchor, inner_left_anchor, inner_right_anchor,
      outer_right_anchor;
  for (size_t i = 0; i < N; i++) {
    tie(outer_left_anchor, inner_left_anchor, inner_right_anchor,
        outer_right_anchor) = get_anchors(i, P);

    total +=
        P[i] *
        (((i - inner_left_anchor) * (outer_right_anchor - inner_right_anchor)) +
         ((inner_left_anchor - outer_left_anchor) * (inner_right_anchor - i)));

    if (DEBUG)
      cout << outer_left_anchor << ", " << inner_left_anchor << ", " << i
           << ", " << inner_right_anchor << ", " << outer_right_anchor << endl;
  }

  cout << total << endl;

  return 0;
}