Window & 滑動窗口 /【模板】單調隊列

WindowWindow

&\&

/調滑動窗口 /【模板】單調隊列

題目鏈接:

1. Window:jzoj 1326jzoj\ 1326
2.滑動窗口 /【模板】單調隊列:luogu 1886luogu\ 1886

WindowWindow:

題目

給你一個長度爲NN的數組,一個長爲KK的滑動的窗體從最左移至最右端,你只能見到窗口的KK個數,每次窗體向右移動一位,如下表:
在這裏插入圖片描述
你的任務是找出窗口在各位置時的 max value, min value.\ max\ value,\ min\ value.

輸入

11nn , kk , 第22行爲長度爲nn的數組,每個數:2 ⁣ ⁣109 ⁣ ⁣2 ⁣ ⁣109-2\!*\!10^9\!\sim\!2\!*\!10^9

輸出

22行,第11行每個位置的 min value\ min\ value,第22行每個位置的 max value\ max\ value

數據範圍

數據範圍:
20%n ⁣<= ⁣500;20\%: n\!<=\!500;
50%n ⁣<= ⁣100000;50\%: n\!<=\!100000;
100%n ⁣<= ⁣1000000;100\%: n\!<=\!1000000;

/調滑動窗口 /【模板】單調隊列:

題目

有一個長爲 nn 的序列 aa,以及一個大小爲 kk 的窗口。現在這個從左邊開始向右滑動,每次滑動一個單位,求出每次滑動後窗口中的最大值和最小值。

例如:

The array is [1,3,1,3,5,3,6,7], and k = 3The\ array\ is\ [1,3,-1,-3,5,3,6,7],\ and\ k\ =\ 3。

輸入

輸入一共有兩行,第一行有兩個正整數 n,kn,k。 第二行 nn 個整數,表示序列 aa

輸出

輸出共兩行,第一行爲每次窗口滑動的最小值
第二行爲每次窗口滑動的最大值

樣例輸入

8 3
1 3 -1 -3 5 3 6 7

樣例輸出

-1 -3 -3 -3 3 3
3 3 5 5 6 7

數據範圍

對於 50%50\% 的數據,1n1051 \le n \le 10^5
對於 100%100\% 的數據,1kn1061\le k \le n \le 10^6ai[231,231])a_i \in [-2^{31},2^{31}])

思路與代碼:

思路

這道題就是一道單調隊列。

我們先要去輸出最小的,就我們就維護一個從小到大的數組,每次都插入當前的那個數,然後把在它前面比它大的數給踢掉。(因爲要插入這個數而且又要維護數組從小到大)然後我們在踢出一個數,這時候不是踢出數組中的數,而是要看踢出的數是不是數組中的第一個數(因爲這個數可能在讀入的時候就被踢掉了)

而我們要輸出最大的,就是和輸出最小的相反的就是了。
(即從小變大變成從大變小,踢掉比它大的變成踢掉比它小的)

(要用long longlong\ long

代碼

#include<cstdio>
#define ll long long

using namespace std;

struct node {
	ll num, x;
}f[1000001];
ll n, k, a[1000001], h, t;

int main() {
	scanf("%lld %lld", &n, &k);//讀入
	
	for (int i = 1; i <= n; i++) 
		scanf("%lld", &a[i]);//讀入
	
	h = 1;//初始化
	t = 0;
	for (ll i = 1; i <= n; i++) {
		while (a[i] <= f[t].x && t >= h) t--;//維護從小到大的數組
		f[++t] = (node){i, a[i]};//插入
		if (i >= k) {
			while (h <= t && f[h].num + k - 1 < i) h++;//踢出隊列
			printf("%d ", f[h].x);//輸出
		}
	}
	
	putchar('\n');
	
	h = 1;//初始化
	t = 0;
	for (ll i = 1; i <= n; i++) {
		while (a[i] >= f[t].x && t >= h) t--;//維護從大到小的數組
		f[++t] = (node){i, a[i]};//插入
		if (i >= k) {
			while (h <= t && f[h].num + k - 1 < i) h++;//踢出隊列
			printf("%d ", f[h].x);//輸出
		}
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章