Lilliput Steps

小さな一歩から着実に. 数学やプログラミングのことを書きます.

PKU 2823 - Sliding Window

問題文 : Sliding Window

解法 :

見た感じセグメント木でもよさそうだが, 蟻本でdequeを使うO(N) 解法が紹介されていたので, dequeの練習がてら書いてみた. dequeステキ, 便利.
やはり書くと分かりやすい.

dqでは, i < j かつ a[i] < a[j] となるようにdequeにデータを詰めていく.
dq2では, i < j かつ a[i] > a[j] となるようにdequeにデータを詰めていく.

使い終わりのときには先頭に来ている(もしくは捨てられている) ので, 除去は O(1) で実現できる.

コード :

#include <cstdio>
#include <deque>
#include <algorithm>

using namespace std;

int a[1000000];
int x[1000000], y[1000000];
deque<int> dq, dq2;

int main()
{
	int n, k;
	scanf("%d %d", &n, &k);
	
	for (int i = 0; i < n; i++) scanf("%d", a + i);
	
	for (int i = 0; i < k - 1; i++){
		while (dq.size() && a[dq[dq.size() - 1]] >= a[i]) dq.pop_back();
		dq.push_back(i);
		
		while (dq2.size() && a[dq2[dq2.size() - 1]] <= a[i]) dq2.pop_back();
		dq2.push_back(i);
	}
	
	for (int i = 0, j; (j = i + k - 1) < n; i++){
		while (dq.size() && a[dq[dq.size() - 1]] >= a[j]) dq.pop_back();
		dq.push_back(j);
		while (dq2.size() && a[dq2[dq2.size() - 1]] <= a[j]) dq2.pop_back();
		dq2.push_back(j);
		
		x[i] = a[dq[0]];
		y[i] = a[dq2[0]];
		if (dq[0] == i) dq.pop_front();
		if (dq2[0] == i) dq2.pop_front();
	}
	
	for (int i = 0; i <= n - k; i++) printf("%d%c", x[i], i == n - k ? '\n' : ' ');
	for (int i = 0; i <= n - k; i++) printf("%d%c", y[i], i == n - k ? '\n' : ' ');
	return (0);
}