coloriot

HA_63_sybarrays

Aug 2nd, 2025
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.10 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <set>
  4. #include <utility>
  5. #include <iterator>
  6. using namespace std;
  7.  
  8. // Класс, поддерживающий скользящее окно
  9. // Оно может:
  10. // - вставлять удалять
  11. // - возвращать максимум
  12. // - получать минимальные разницы между соседями
  13.  
  14. class SlidingWindow {
  15. public:
  16.     void insert(int x) {
  17.         if (elems.empty()) {
  18.             elems.insert(x);
  19.             return;
  20.         }
  21.         auto it = elems.lower_bound(x);
  22.         if (it != elems.end() && *it == x) {
  23.             // Дублирующиеся значения: разности между одинаковыми = 0,
  24.             // это сразу нарушит условие (т.к. 0 > max невозможно), но
  25.             // всё равно корректно поддержим структуру.
  26.             // Обрабатываем как обычную вставку.
  27.         }
  28.         auto prev = (it == elems.begin()) ? elems.end() : prev_it(it);
  29.         auto next = (it == elems.end()) ? elems.end() : it;
  30.  
  31.         if (prev != elems.end() && next != elems.end()) {
  32.             // Удаляем старую разницу между prev и next
  33.             long long old_gap = (long long)(*next) - (long long)(*prev);
  34.             auto fg = gaps.find(old_gap);
  35.             if (fg != gaps.end()) gaps.erase(fg);
  36.         }
  37.  
  38.         if (prev != elems.end()) {
  39.             long long gap = (long long)x - (long long)(*prev);
  40.             gaps.insert(gap);
  41.         }
  42.         if (next != elems.end()) {
  43.             long long gap = (long long)(*next) - (long long)x;
  44.             gaps.insert(gap);
  45.         }
  46.  
  47.         elems.insert(x);
  48.     }
  49.  
  50.     void erase(int x) {
  51.         auto it = elems.find(x);
  52.         if (it == elems.end()) return; // нет такого
  53.  
  54.         auto prev = (it == elems.begin()) ? elems.end() : prev_it(it);
  55.         auto next = next_it(it);
  56.  
  57.         if (prev != elems.end()) {
  58.             long long gap = (long long)x - (long long)(*prev);
  59.             auto fg = gaps.find(gap);
  60.             if (fg != gaps.end()) gaps.erase(fg);
  61.         }
  62.         if (next != elems.end()) {
  63.             long long gap = (long long)(*next) - (long long)x;
  64.             auto fg = gaps.find(gap);
  65.             if (fg != gaps.end()) gaps.erase(fg);
  66.         }
  67.  
  68.         if (prev != elems.end() && next != elems.end()) {
  69.             long long new_gap = (long long)(*next) - (long long)(*prev);
  70.             gaps.insert(new_gap);
  71.         }
  72.  
  73.         elems.erase(it);
  74.     }
  75.  
  76.     bool empty() const {
  77.         return elems.empty();
  78.     }
  79.  
  80.     // Возвращает текущий максимум (предполагаем, что не пусто)
  81.     int get_max() const {
  82.         return *elems.rbegin();
  83.     }
  84.  
  85.     // Возвращает минимальную соседнюю разницу; если <2 элементов, возвращаем бесконечность
  86.     long long min_gap() const {
  87.         if (gaps.empty()) return LLONG_MAX;
  88.         return *gaps.begin();
  89.     }
  90.  
  91.     size_t size() const {
  92.         return elems.size();
  93.     }
  94.  
  95. private:
  96.     set<int> elems;
  97.     multiset<long long> gaps;
  98.  
  99.     // Вспомогательные: безопасно получить prev/next итератор
  100.     set<int>::iterator prev_it(set<int>::iterator it) const {
  101.         return std::prev(it);
  102.     }
  103.     set<int>::iterator next_it(set<int>::iterator it) const {
  104.         auto nxt = std::next(it);
  105.         if (nxt == elems.end()) return elems.end();
  106.         return nxt;
  107.     }
  108. };
  109.  
  110. pair<int,int> find_best_subarray(const vector<int>& V) {
  111.     int n = V.size();
  112.     SlidingWindow window;
  113.     int bestL = 0, bestR = -1; // пусто
  114.     int l = 0;
  115.  
  116.     for (int r = 0; r < n; ++r) {
  117.         window.insert(V[r]);
  118.  
  119.         // Сдвигаем левый указатель, пока условие нарушается
  120.         while (!window.empty()) {
  121.             int current_max = window.get_max();
  122.             long long mg = window.min_gap();
  123.             if (window.size() >= 2 && mg <= current_max) {
  124.                 // Нарушается, сдвигаем l
  125.                 window.erase(V[l]);
  126.                 ++l;
  127.             } else {
  128.                 break;
  129.             }
  130.         }
  131.  
  132.         // Проверка: допустимое окно
  133.         if ((int)window.size() > (bestR - bestL + 1)) {
  134.             // size >=1 всегда удовлетворяет (для size==1: нет пары, условие тривиально)
  135.             bestL = l;
  136.             bestR = r;
  137.         }
  138.     }
  139.     return {bestL, bestR};
  140. }
  141.  
  142. int main() {
  143.     vector<int> V = {-8, 6, 4, 0, 2, 0, 12, -6, -20, -5, -3, 1, -4};
  144.     auto [l, r] = find_best_subarray(V);
  145.     if (l <= r) {
  146.         cout << "Best subarray: [" << l << ", " << r << "]\n";
  147.         cout << "Elements: ";
  148.         for (int i = l; i <= r; ++i) {
  149.             cout << V[i] << (i < r ? ", " : "\n");
  150.         }
  151.     } else {
  152.         cout << "There is no subarray\n";
  153.     }
  154.     return 0;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment