ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SlidingDeque
    232's competitive-programming templates. 2024. 8. 23. 21:48
    template <typename T, typename F>
    struct SlidingDeque {
      F func;
      std::vector<T> head;
      std::vector<T> tail;
      std::vector<T> fhead;
      std::vector<T> ftail;
    
      SlidingDeque(const F& _func = F {}) : func(_func) {
        void(0);
      }
    
      [[nodiscard]] int size() const {
        return int(head.size()) + int(tail.size());
      }
    
      [[nodiscard]] bool empty() const {
        return size() == 0;
      }
    
      [[nodiscard]] const T& operator [] (int index) const {
        assert(0 <= index && index < size());
        return (index < int(head.size()) ? head[int(head.size()) - 1 - index] : tail[index - int(head.size())]);
      }
    
      [[nodiscard]] const T& front() const {
        assert(!empty());
        return head.empty() ? tail.front() : head.back();
      }
    
      [[nodiscard]] const T& back() const {
        assert(!empty());
        return tail.empty() ? head.front() : tail.back();
      }
    
      [[nodiscard]] T get() const {
        if (!fhead.empty() && !ftail.empty()) {
          return func(fhead.back(), ftail.back());
        } else if (!fhead.empty()) {
          return fhead.back();
        } else if (!ftail.empty()) {
          return ftail.back();
        } else {
          assert(false);
        }
      }
    
      void pushFront(const T& x) {
        const T nw = (head.empty() ? x : func(x, fhead.back()));
        head.push_back(x);
        fhead.push_back(std::move(nw));
      }
    
      void pushBack(const T& x) {
        const T nw = (tail.empty() ? x : func(ftail.back(), x));
        tail.push_back(x);
        ftail.push_back(std::move(nw));
      }
    
      void transportToHead() {
        head.insert(head.begin(), tail.rbegin() + int(tail.size()) / 2, tail.rend());
        tail.erase(tail.begin(), tail.end() - int(tail.size()) / 2);
        ftail = {};
        std::partial_sum(head.begin(), head.end(), std::back_inserter(fhead), [&](const T& a, const T& b) {
          return func(b, a);
        });
        std::partial_sum(tail.begin(), tail.end(), std::back_inserter(ftail), func);
      }
    
      void transportToTail() {
        tail.insert(tail.begin(), head.rbegin() + int(head.size()) / 2, head.rend());
        head.erase(head.begin(), head.end() - int(head.size()) / 2);
        fhead = {};
        std::partial_sum(head.begin(), head.end(), std::back_inserter(fhead), [&](const T& a, const T& b) {
          return func(b, a);
        });
        std::partial_sum(tail.begin(), tail.end(), std::back_inserter(ftail), func);
      }
    
      void popFront() {
        assert(!empty());
        if (head.empty()) {
          transportToHead();
        }
        head.pop_back();
        fhead.pop_back();
      }
    
      void popBack() {
        assert(!empty());
        if (tail.empty()) {
          transportToTail();
        }
        tail.pop_back();
        ftail.pop_back();
      }
    
      void clear() {
        head = {};
        tail = {};
        fhead = {};
        ftail = {};
      }
    };

    '232's competitive-programming templates.' 카테고리의 다른 글

    Queue  (0) 2024.08.23
    Deque  (0) 2024.08.23
    LineContainer  (0) 2024.08.22
    (useless) MaximumFlow (Edmond Karp)  (0) 2024.08.21
    (useless) getConvexHull  (0) 2024.08.21
Designed by Tistory.