sotanishy's competitive programming library

sotanishy's code snippets for competitive programming

View the Project on GitHub sotanishy/cp-library-cpp

:heavy_check_mark: Sliding Window Aggregation
(data-structure/sliding_window_aggregation.hpp)

Description

Sliding window aggregation は,半群 $(T, \cdot)$ を扱い,要素の総和の計算が可能なキューである.スタックを2つ用いてキューをシミュレートする.

Operations

Reference

Verified with

Code

#pragma once
#include <cassert>
#include <stack>
#include <utility>

template <typename S>
class SlidingWindowAggregation {
    using T = typename S::T;

   public:
    void push(const T& x) {
        if (back.empty())
            back.emplace(x, x);
        else
            back.emplace(x, S::op(back.top().second, x));
    }

    void pop() {
        assert(!empty());
        if (front.empty()) {
            T x = back.top().first;
            back.pop();
            front.emplace(x, x);
            while (!back.empty()) {
                x = back.top().first;
                back.pop();
                front.emplace(x, S::op(x, front.top().second));
            }
        }
        front.pop();
    }

    bool empty() const { return front.empty() && back.empty(); }

    T fold() const {
        assert(!empty());
        if (front.empty()) return back.top().second;
        if (back.empty()) return front.top().second;
        return S::op(front.top().second, back.top().second);
    }

   private:
    std::stack<std::pair<T, T>> front, back;
};
#line 2 "data-structure/sliding_window_aggregation.hpp"
#include <cassert>
#include <stack>
#include <utility>

template <typename S>
class SlidingWindowAggregation {
    using T = typename S::T;

   public:
    void push(const T& x) {
        if (back.empty())
            back.emplace(x, x);
        else
            back.emplace(x, S::op(back.top().second, x));
    }

    void pop() {
        assert(!empty());
        if (front.empty()) {
            T x = back.top().first;
            back.pop();
            front.emplace(x, x);
            while (!back.empty()) {
                x = back.top().first;
                back.pop();
                front.emplace(x, S::op(x, front.top().second));
            }
        }
        front.pop();
    }

    bool empty() const { return front.empty() && back.empty(); }

    T fold() const {
        assert(!empty());
        if (front.empty()) return back.top().second;
        if (back.empty()) return front.top().second;
        return S::op(front.top().second, back.top().second);
    }

   private:
    std::stack<std::pair<T, T>> front, back;
};
Back to top page