Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Sliding Minimum Element

For a given array $a_1, a_2, a_3, ... , a_N$ of $N$ elements and an integer $L$, find the minimum of each possible sub-arrays with size $L$ and print them from the beginning. For example, for an array $\{1, 7, 7, 4, 8, 1, 6\}$ and $L = 3$, the possible sub-arrays with size $L = 3$ includes $\{1, 7, 7\}$, $\{7, 7, 4\}$, $\{7, 4, 8\}$, $\{4, 8, 1\}$, $\{8, 1, 6\}$ and the minimum of each sub-array is 1, 4, 4, 1, 1 respectively.

Constraints

$1 \leq N \leq 10^6$

$1 \leq L \leq 10^6$

$1 \leq a_i \leq 10^9$

$L \leq N$

Input

The input is given in the following format.

$N$ $L$

$a_1$ $a_2$ ... $a_N$

Output

Print a sequence of the minimum in a line. Print a space character between adjacent elements.

Sample Input 1

7 3
1 7 7 4 8 1 6

Sample Output 1

1 4 4 1 1

Solution in C++14 (judge verdict: Accepted)


#include <iostream>
#include <algorithm>
#include <array>
#include <cstdint>
#include <climits>
#include <functional>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>


using int32 = std::int_fast32_t;
using int64 = std::int_fast64_t;
using uint32 = std::uint_fast32_t;
using uint64 = std::uint_fast64_t;

#ifndef __GNUC__
std::uint_fast32_t __builtin_clz(std::uint_fast32_t c) {
	std::uint_fast32_t t = 31;
	if (c & 0xFFFF0000) { c &= 0xFFFF0000;t ^= 16; }
	if (c & 0xFF00FF00) { c &= 0xFF00FF00;t ^= 8; }
	if (c & 0xF0F0F0F0) { c &= 0xF0F0F0F0;t ^= 4; }
	if (c & 0xCCCCCCCC) { c &= 0xCCCCCCCC;t ^= 2; }
	if (c & 0xAAAAAAAA) { c &= 0xAAAAAAAA;t ^= 1; }
	return t;
}
#endif
template<typename Semigroup>
class sparse_table {
	using uint32 = std::uint_fast32_t;
	struct block {
		Semigroup table[5][32];
		block() {}
		void build(){
			for (uint32 i = 1;i < 5;++i) {
				for (uint32 j = (uint32)1 << i;j < 32;j += (uint32)1 << (i + 1)) {
					table[i][j - 1] = table[0][j - 1];
					for (uint32 k = 2;k <= (uint32)1 << i;++k) {
						table[i][j - k] = table[0][j - k] + table[i][j - k + 1];
					}
					table[i][j] = table[0][j];
					for (uint32 k = 1;k < (uint32)1 << i;++k) {
						table[i][j + k] = table[i][j + k - 1] + table[0][j + k];
					}
				}
			}
		}
		Semigroup range(const uint32 begin, const uint32 end)const {
			if (begin == end) return table[0][begin];
			const uint32 p = 31 ^ __builtin_clz(begin^end);
			return table[p][begin] + table[p][end];
		}
	};
	std::vector<std::vector<Semigroup>> table;
	std::vector<block> blocks;
public:
	sparse_table(const std::vector<Semigroup> &array) {
		if (!array.size()) { return; }
		uint32 c = 31 ^ __builtin_clz(array.size());
		if (((uint32)1 << c) != array.size()) ++c;
		if (c < 5) c = 5;
		const uint32 s = (uint32)1 << c;
		blocks = std::vector<block>(s >> 5);
		for (uint32 i = 0;i < array.size();++i) {
			blocks[i >> 5].table[0][i & 31] = array[i];
		}
		for (uint32 i = array.size();i < s;++i) {
			blocks[i >> 5].table[0][i & 31] = Semigroup();
		}
		for (uint32 i = 0;i < s >> 5;++i) {
			blocks[i].build();
		}
		if (c == 5) return;
		c -= 5;
		const uint32 size = (uint32)1 << c;
		table = std::vector<std::vector<Semigroup>>(c, std::vector<Semigroup>(size));
		for (uint32 i = 0;i < size;++i) {
			table[0][i] = blocks[i].range(0, 31);
		}
		for (uint32 i = 1;i < c;++i) {
			for (uint32 j = (uint32)1 << i;j < size;j += (uint32)1 << (i + 1)) {
				table[i][j - 1] = table[0][j - 1];
				for (uint32 k = 2;k <= (uint32)1 << i;++k) {
					table[i][j - k] = table[0][j - k] + table[i][j - k + 1];
				}
				table[i][j] = table[0][j];
				for (uint32 k = 1;k < (uint32)1 << i;++k) {
					table[i][j + k] = table[i][j + k - 1] + table[0][j + k];
				}
			}
		}
	}
	Semigroup range(const uint32 begin, const uint32 end)const {
		const uint32 L = (begin >> 5) + 1;
		const uint32 R = (end - 1) >> 5;
		if (L < R) {
			if (L +1== R) {
				return blocks[L - 1].range(begin & 31, 31)
					+ table[0][L] + blocks[R].range(0, (end - 1) & 31);
			}
			const uint32 p = 31 ^ __builtin_clz(L^(R-1));
			return blocks[L - 1].range(begin & 31, 31) + table[p][L]
				+ table[p][R-1] + blocks[R].range(0, (end - 1) & 31);
		}
		if (L == R) {
			return blocks[L - 1].range(begin & 31, 31) + blocks[L].range(0, (end - 1) & 31);
		}
		return blocks[R].range(begin & 31, (end - 1) & 31);
	}
};

template<typename T>
struct MIN {
	T e;
	MIN(T x = std::numeric_limits<T>::max()) :e(x) {}
	MIN operator~() {
		return *this;
	}
	MIN operator+(const MIN &other)const {
		if (e < other.e) return *this;
		return other;
	};
	MIN operator*(const MIN &other)const {
		return other;
	}
};
template<typename T>
void uscan(T &d) {
	d = 0;unsigned char c = 0;
	while (c < '0' || '9' < c) c = fgetc(stdin);
	while ('0' <= c&&c <= '9') {
		d = (d << 3) + (d << 1) + c - '0';c = fgetc(stdin);
	}
}
int main(void) {
	using uint32 = std::uint_fast32_t;
	using M = MIN<uint32>;
	uint32 n, l;
	uscan(n);uscan(l);
	std::vector<M> a(n);
	for (uint32 i = 0;i < n;++i)uscan(a[i].e);
	sparse_table<M> T(a);
	printf("%u", T.range(0, l).e);
	for (uint32 i = 1;i <= n - l;++i) {
		printf(" %u", T.range(i, i + l).e);
	}
	printf("\n");
	return 0;
}