Problem p02941 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <map>
#include <set>
#include <stdio.h>
#include <utility>
#include <vector>

// Attributes
typedef long long int lld;
int n;
lld operation = 0;
std::map<lld, std::vector<int>> indices;
std::vector<lld> init, result;

// Pop largest indices one. Return {result value, index}
std::pair<lld, int> pop_largest() {
  auto largest_pointer = indices.rbegin();
  lld largest = largest_pointer->first;
  int index_candidate = largest_pointer->second.back();
  largest_pointer->second.pop_back();
  if (largest_pointer->second.empty())
    indices.erase(largest);
  return {largest, index_candidate};
}

// Push
void push(lld value, int index) { indices[value].push_back(index); }
void push(std::pair<lld, int> info) { push(info.first, info.second); }

// Near values {prev, next}
std::pair<lld, lld> near_values(int index) {
  int previndex = (index + n - 1) % n, nextindex = (index + 1) % n;
  return {result[previndex], result[nextindex]};
}
// Reduce given index by count.
void reduce(int index, lld count) {
  std::pair<lld, lld> near_values_ = near_values(index);
  result[index] -= count * (near_values_.first + near_values_.second);
}

void printResult() {
  printf("Current result after %lld operation: [", operation);
  for (int i = 0; i < n; i++)
    printf("%lld, ", result[i]);
  printf("]\n");
}

int main(void) {

  // freopen("VScode/IO/input.txt", "r", stdin);
  // freopen("VScode/IO/output.txt", "w", stdout);

  // Get input
  bool ok = true;
  scanf("%d", &n);
  init.resize(n);
  result.resize(n);
  for (int i = 0; i < n; i++)
    scanf("%lld", &init[i]);
  for (int i = 0; i < n; i++) {
    scanf("%lld", &result[i]);
    if (result[i] < init[i])
      ok = false;
    else if (result[i] > init[i])
      push(result[i], i);
  }

  // Reduce from the largest
  // printResult();
  while (!indices.empty()) {

    // Pop two largest values
    std::pair<lld, int> largest_first = pop_largest();
    lld current_value = largest_first.first;
    int i = largest_first.second;
    lld targetValue = init[i];
    std::pair<lld, lld> near = near_values(i); // near values

    if (!indices.empty()) {
      std::pair<lld, int> largest_second = pop_largest();
      lld secondaryTarget = largest_second.first;
      if (targetValue < secondaryTarget)
        targetValue = secondaryTarget;
      push(largest_second);
    }

    // Go
    lld reducable_count =
        (current_value - targetValue) / (near.first + near.second);
    // printf("Largest: (%lld, index %d), near values (%lld, %lld), targetValue
    // %lld\n", result[i], i, near.first, near.second, targetValue);
    if (reducable_count <= 0) {
      if (current_value - near.first - near.second >= init[i]) {
        reducable_count = 1;
      } else {
        // printf("Reducable count is %lld, break program.\n", reducable_count);
        ok = false;
        break;
      }
    }
    // printf("Reducable count %lld\n", reducable_count);
    reduce(i, reducable_count);
    operation += reducable_count;
    // printResult();

    // Push again
    if (result[i] > init[i])
      push(result[i], i); // Push if only still remaining
  }
  printf("%lld\n", ok ? operation : -1);
  return 0;
}

Fixed submission:
#include <map>
#include <set>
#include <stdio.h>
#include <utility>
#include <vector>

// Attributes
typedef long long int lld;
int n;
lld operation = 0;
std::map<lld, std::vector<int>> indices;
std::vector<lld> init, result;

// Pop largest indices one. Return {result value, index}
std::pair<lld, int> pop_largest() {
  auto largest_pointer = indices.rbegin();
  lld largest = largest_pointer->first;
  int index_candidate = largest_pointer->second.back();
  largest_pointer->second.pop_back();
  if (largest_pointer->second.empty())
    indices.erase(largest);
  return {largest, index_candidate};
}

// Push
void push(lld value, int index) { indices[value].push_back(index); }
void push(std::pair<lld, int> info) { push(info.first, info.second); }

// Near values {prev, next}
std::pair<lld, lld> near_values(int index) {
  int previndex = (index + n - 1) % n, nextindex = (index + 1) % n;
  return {result[previndex], result[nextindex]};
}
// Reduce given index by count.
void reduce(int index, lld count) {
  std::pair<lld, lld> near_values_ = near_values(index);
  result[index] -= count * (near_values_.first + near_values_.second);
}

void printResult() {
  printf("Current result after %lld operation: [", operation);
  for (int i = 0; i < n; i++)
    printf("%lld, ", result[i]);
  printf("]\n");
}

int main(void) {

  // freopen("VScode/IO/input.txt", "r", stdin);
  // freopen("VScode/IO/output.txt", "w", stdout);

  // Get input
  bool ok = true;
  scanf("%d", &n);
  init.resize(n);
  result.resize(n);
  for (int i = 0; i < n; i++)
    scanf("%lld", &init[i]);
  for (int i = 0; i < n; i++) {
    scanf("%lld", &result[i]);
    if (result[i] < init[i])
      ok = false;
    else if (result[i] > init[i])
      push(result[i], i);
  }

  // Reduce from the largest
  // printResult();
  while (!indices.empty()) {

    // Pop two largest values
    std::pair<lld, int> largest_first = pop_largest();
    lld current_value = largest_first.first;
    int i = largest_first.second;
    lld targetValue = init[i];
    std::pair<lld, lld> near = near_values(i); // near values

    /*if(!indices.empty()){
        std::pair<lld, int> largest_second = pop_largest();
        lld secondaryTarget = largest_second.first;
        if(targetValue < secondaryTarget) targetValue = secondaryTarget;
        push(largest_second);
    }*/
    if (targetValue < near.first + near.second + 1)
      targetValue = near.first + near.second + 1;

    // Go
    lld reducable_count =
        (current_value - targetValue) / (near.first + near.second);
    // printf("Largest: (%lld, index %d), near values (%lld, %lld), targetValue
    // %lld\n", result[i], i, near.first, near.second, targetValue);
    if (reducable_count <= 0) {
      if (current_value - near.first - near.second >= init[i]) {
        reducable_count = 1;
      } else {
        // printf("Reducable count is %lld, break program.\n", reducable_count);
        ok = false;
        break;
      }
    }
    // printf("Reducable count %lld\n", reducable_count);
    reduce(i, reducable_count);
    operation += reducable_count;
    // printResult();

    // Push again
    if (result[i] > init[i])
      push(result[i], i); // Push if only still remaining
  }
  printf("%lld\n", ok ? operation : -1);
  return 0;
}