Джим та хмарочоси#11720

Джим та хмарочоси (Розбір)

Уявімо, що ми будуємо "стіни" з блоків однакової висоти.

Пара утворює "коридор", якщо між цими стінами немає більшої стіни. Для розв'язання задачі будемо використовувати монотонний стек. Стек зберігає пари (value, count):

Тобто:

Наприклад, нехай поточне число дорівнює a = 5, і раніше воно вже зустрічалося рази (тобто на даний момент число a = 5 зустрічається четвертий раз). Припустимо, що між всіма цими входженнями числа знаходяться тільки менші елементи. Тоді кількість нових пар індексів , де — поточний індекс і виконується умова h_i = h_j = a, буде дорівнювати .

При обробці чергового числа h_i:

Приклад

Розглянемо перший тест.

Реалізація алгоритму

Читаємо вхідні дані.

scanf("%d", &n);
vector<int> v(n);
for (i = 0; i < n; ++i)
  scanf("%d", &v[i]);

У змінній будемо зберігати кількість знайдених пар індексів.

res = 0;

Оголосимо стек пар.

stack<pair<int, int>> st;

Послідовно обробляємо всі числа масиву.

for (i = 0; i < v.size(); i++)
{

Поки на вершині стека знаходиться число, менше , видаляємо його зі стека.

  while (!st.empty() && st.top().first < v[i])
    st.pop();

Якщо на вершині стека знаходиться число, рівне , і воно зустрічалося раніше разів (значення зберігається в st.top().second), то збільшуємо відповідь на . Після цього оновлюємо кількість появ , замінивши його на x + 1.

  if (!st.empty() && v[i] == st.top().first)
  {
    res += st.top().second;
    st.top().second += 1;
  }
  else

Якщо ж число зустрілося вперше, то додаємо в стек пару (v[i], 1).

    st.push({ v[i], 1 });
}

Виводимо відповідь.

printf("%lld\n", res);