sotanishy's code snippets for competitive programming
#include "data-structure/sliding_window_aggregation.hpp"
Sliding window aggregation は,半群 $(T, \cdot)$ を扱い,要素の総和の計算が可能なキューである.スタックを2つ用いてキューをシミュレートする.
void push(T x)
void pop()
bool empty()
T fold()
#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;
};