Комфорт Василька#500

Комфорт Василька (Editorial)

Автор: Андрій Холод

Роздробник: Павло Цікалишин

Розбір підготовано: Костянтин Денисов

Потрібно знайти найдовший підвідрізок масиву a_1,\dots,a_n, для якого \max(a_l,\dots,a_r) - \min(a_l,\dots,a_r) \le k. Це класична задача на два вказівники з підтримкою поточного мінімуму і максимуму в вікні.

Якщо фіксувати праву межу і збільшувати , то не зростає, а не спадає, отже різниця не збільшується. Тому можна рухати два вказівники: розширювати вікно вправо, а коли умова порушується — зсувати ліву межу, поки знову не стане добре.

Проблема: потрібно швидко знати і у поточному вікні [l,r]. Для цього підтримуємо std::multiset на елементах поточного вікна.

Алгоритм завжди підтримує інваріант: після внутрішнього циклу вікно [l,r] є комфортним. Для кожного ми мінімізуємо (зсуваємо його лише поки треба), тому довжина r-l+1 є максимальною серед усіх комфортних підвідрізків, що закінчуються в . Максимум по всіх дає відповідь задачі.

Складність. Кожен індекс додається в множину рівно один раз і видаляється не більше одного разу, тому загальний час O(n \log{n}), пам'ять .