Nyaan's Library

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:heavy_check_mark: Slide Window Aggrigation (deque)
(data-structure/slide-window-aggregation-deque.hpp)

Verified with

Code

#pragma once

#include <vector>
using namespace std;

template <typename T, typename F>
struct SlideWindowAggregationDeque {
  vector<T> a0, a1, r0, r1;
  F f;
  T I;

  SlideWindowAggregationDeque(F _f, T _i) : f(_f), I(_i) {}

 private:
  T get0() const { return r0.empty() ? I : r0.back(); }
  T get1() const { return r1.empty() ? I : r1.back(); }

  void push0(const T &x) {
    a0.push_back(x);
    r0.push_back(f(x, get0()));
  }
  void push1(const T &x) {
    a1.push_back(x);
    r1.push_back(f(get1(), x));
  }
  void rebalance() {
    int n = a0.size() + a1.size();
    int s0 = n / 2 + (a0.empty() ? n % 2 : 0);
    vector<T> a{a0};
    reverse(begin(a), end(a));
    copy(begin(a1), end(a1), back_inserter(a));
    a0.clear(), r0.clear();
    a1.clear(), r1.clear();
    for (int i = s0 - 1; i >= 0; i--) push0(a[i]);
    for (int i = s0; i < n; i++) push1(a[i]);
  }

 public:
  void push_front(const T &t) { push0(t); }
  void push_back(const T &t) { push1(t); }
  T front() const { return a0.empty() ? a1.front() : a0.back(); }
  T back() const { return a1.empty() ? a0.front() : a1.back(); }
  void pop_front() {
    if (a0.empty()) rebalance();
    assert(!a0.empty());
    a0.pop_back(), r0.pop_back();
  }
  void pop_back() {
    if (a1.empty()) rebalance();
    assert(!a1.empty());
    a1.pop_back(), r1.pop_back();
  }
  T query() { return f(get0(), get1()); }
};

/**
 * @brief Slide Window Aggrigation (deque)
 */
#line 2 "data-structure/slide-window-aggregation-deque.hpp"

#include <vector>
using namespace std;

template <typename T, typename F>
struct SlideWindowAggregationDeque {
  vector<T> a0, a1, r0, r1;
  F f;
  T I;

  SlideWindowAggregationDeque(F _f, T _i) : f(_f), I(_i) {}

 private:
  T get0() const { return r0.empty() ? I : r0.back(); }
  T get1() const { return r1.empty() ? I : r1.back(); }

  void push0(const T &x) {
    a0.push_back(x);
    r0.push_back(f(x, get0()));
  }
  void push1(const T &x) {
    a1.push_back(x);
    r1.push_back(f(get1(), x));
  }
  void rebalance() {
    int n = a0.size() + a1.size();
    int s0 = n / 2 + (a0.empty() ? n % 2 : 0);
    vector<T> a{a0};
    reverse(begin(a), end(a));
    copy(begin(a1), end(a1), back_inserter(a));
    a0.clear(), r0.clear();
    a1.clear(), r1.clear();
    for (int i = s0 - 1; i >= 0; i--) push0(a[i]);
    for (int i = s0; i < n; i++) push1(a[i]);
  }

 public:
  void push_front(const T &t) { push0(t); }
  void push_back(const T &t) { push1(t); }
  T front() const { return a0.empty() ? a1.front() : a0.back(); }
  T back() const { return a1.empty() ? a0.front() : a1.back(); }
  void pop_front() {
    if (a0.empty()) rebalance();
    assert(!a0.empty());
    a0.pop_back(), r0.pop_back();
  }
  void pop_back() {
    if (a1.empty()) rebalance();
    assert(!a1.empty());
    a1.pop_back(), r1.pop_back();
  }
  T query() { return f(get0(), get1()); }
};

/**
 * @brief Slide Window Aggrigation (deque)
 */
Back to top page