1. 程式人生 > >poj 2823 滑動視窗 單調佇列

poj 2823 滑動視窗 單調佇列

Description

An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: 
The array is [1 3 -1 -3 5 3 6 7]
, and k is 3.
Window position Minimum value Maximum value
[1  3  -1] -3  5  3  6  7  -1 3
 1 [3  -1  -3] 5  3  6  7  -3 3
 1  3 [-1  -3  5] 3  6  7  -3 5
 1  3  -1 [-3  5  3] 6  7  -3 5
 1  3  -1  -3 [5  3  6] 7  3 6
 1  3  -1  -3  5 [3  6  7] 3 7

Your task is to determine the maximum and minimum values in the sliding window at each position. 

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line. 

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values. 

Sample Input

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

Sample Output

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

線段樹雖然可以水過,但複雜度比較高,可以用更優的單調佇列方法。

#include <iostream>
#include <cstdio>
using namespace std;

const int N = 1000005;

struct Elem
{
	int val;
	int pos;
};

Elem maxque[N];
Elem minque[N];
int maxhead, minhead, maxtail, mintail;
int maxans[N];
int minans[N];
int cur;

int main()
{
	int n, w, num;
	scanf("%d%d", &n, &w);
	minhead = mintail = 0;
	maxhead = maxtail = 0;
	cur = 0;
	for (int i = 0; i < w; ++i)
	{
		scanf("%d", &num);
		
		while (minhead < mintail && minque[mintail - 1].val >= num) --mintail;
		minque[mintail].val = num;
		minque[mintail].pos = i;
		++mintail;

		while (maxhead < maxtail && maxque[maxtail - 1].val <= num) --maxtail;
		maxque[maxtail].val = num;
		maxque[maxtail].pos = i;
		++maxtail;
	}
	for (int i = w; i < n; ++i)
	{
		minans[cur] = minque[minhead].val;
		maxans[cur] = maxque[maxhead].val;
		++cur;

		scanf("%d", &num);

		while (minhead < mintail && i - minque[minhead].pos >= w) ++minhead;
		while (minhead < mintail && minque[mintail - 1].val >= num) --mintail;
		minque[mintail].val = num;
		minque[mintail].pos = i;
		++mintail;
		
		while (maxhead < maxtail && i - maxque[maxhead].pos >= w) ++maxhead;
		while (maxhead < maxtail && maxque[maxtail - 1].val <= num) --maxtail;
		maxque[maxtail].val = num;
		maxque[maxtail].pos = i;
		++maxtail;
	}
	minans[cur] = minque[minhead].val;
	maxans[cur] = maxque[maxhead].val;
	++cur;
	
	for (int i = 0; i < cur; ++i)
	{
		if (i > 0) putchar(' ');
		printf("%d", minans[i]);
	}
	printf("\n");
	for (int i = 0; i < cur; ++i)
	{
		if (i > 0) putchar(' ');
		printf("%d", maxans[i]);
	}
	printf("\n");

	return 0;
}


相關推薦

poj 2823 滑動視窗 單調佇列

Description An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the very left of the

POJ 2823】Sliding Window 【滑動視窗/單調佇列入門

題目大意 輸入一個長度為n(n≤≤106106)的數列,給定一個長度為k的視窗,讓這個視窗在數列上移動,求移動到每個位置視窗中包含數的最大值和最小值。即設序列為A1,A2,…,AnA1,A2,…,AnA1,A2,…,An,設f(i)=minAi−k+1Ai−k+

#滑動視窗 + 單調佇列# 2018 Multi-University Training Contest 3 Problem A. Ascending Rating

題目連結: http://acm.hdu.edu.cn/showproblem.php?pid=6319   Problem Description Before the start of contest, there are n ICPC cont

poj 2823 Sliding Windows (單調佇列+輸入輸出掛)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 73426

滑動視窗[單調佇列]

傳送門 單調佇列維護最小最大就可以了 #include<bits/stdc++.h> #define N 1000050 using namespace std; int Max[N],Min[N],ans1[N],ans2[N]; int n,k,l1=1,l2=1,r1,

【題解】洛谷P1886 滑動視窗(單調佇列)

(之前從未聽說過這道題目 來到qbxt後大佬們都早就切掉此題了 倍感慚愧qwq) 題目大意就是給定一個序列A與要求的長度k,讓我們輸出A中所有長度為k的區間的最大值和最小值。 看到資料範圍後我們發現暴力會炸掉,所以要考慮比較簡潔的方法。這裡我們維護一個元素單調遞減的佇列求

[POJ2823]Sliding Window 滑動視窗(單調佇列)

題意 剛學單調佇列的時候做過 現在重新做一次 一個很經典的題目   現在有一堆數字共N個數字(N<=10^6),以及一個大小為k的視窗。現在這個從左邊開始向右滑動,每次滑動一個單位,求出每次滑動後窗口中的最大值和最小值。 思路 單調佇列 一個遞增 一個遞減 程式碼

滑動視窗(單調佇列)講解_legend

雙端佇列的應用: (一):長度為k的滑動視窗取最小值:(或者稱為單調佇列) (二):多重揹包問題: -------- (一)長度為k的滑動視窗取最小值: (1)問題背景:slider window 有一個長度為n的陣列,有一個長度為k的滑動視窗,從左往右每次滑動一個元素;求

POJ 2823 Sliding Window (單調佇列)

題目連結 Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the v

POJ 2823 Sliding Window(單調佇列)

題意  長度為n的陣列上有個長度為k的滑窗從左向右移動  求每次移動後滑窗區間的最小值和最大值  輸出兩行  第一行所有最小值  第二行所有最大值 可以用線段樹來做  但是單調佇列更簡單  單調遞增佇列: 隊尾單調入隊(入隊元素大於隊尾元素時直接入隊  否則隊尾出隊直到隊尾

poj 2823 二分法+單調佇列

#include<stdio.h> #include<string.h> #define N  1100000 int a[N]; int fmin[N],fmax[N]; int tmin[N],tmax[N]; int dicmax(int l,

POJ 2823 滑動窗口 單調隊列

r++ 還需要 har pac turn include \n div 還需 模板題 以後再寫= = 還需要二分優化(減少常數?) #include<iostream> #include<cstdio> using namespace

2823 Sliding Window (單調佇列求解區間最值)

POJ - 2823 Time Limit: 12000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu Descri

POJ 2823 (從經典滑動視窗最大值問題入門單調佇列)

題目連結 題目大意 輸入一個長度為n(n≤106)的數列,給定一個長度為k的視窗,讓這個視窗在數列上移動,求移動到每個位置視窗中包含數的最大值和最小值。即設序列為A1,A2,…,An,設f(i)=min{Ai−k+1,Ai−k+2,…,Ak} ,g(

[NOIP模擬][POJ 2823][單調佇列]滑動的窗戶(Sliding Window)

題目描述: 題目連結: POJ 2823 http://poj.org/problem?id=2823 在一個包含 n 個元素的陣列上,有一個長度為 k 的窗戶在從左向右滑動。窗戶每滑動到一個位置,我們都可以看到 k 個元素在窗戶中。如下的例子所示,假設陣

POJ - 2823 Sliding Window【單調佇列優化dp && c++快讀】

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 72718 &nb

POJ-2823-Sliding Window (單調佇列

原題連結: http://poj.org/problem?id=2823 An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the ver

單調佇列 POJ 2823 Sliding Window

  Sliding Window An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich is moving from

單調佇列滑動視窗):紀念我因head tail的WA

初值似乎沒什麼用 然後我就WA了。。。 如果初值為h1=1,t1=0,h2=1,h1=0; 判斷head tail是加等號 如果h1==t1 可以不加 程式碼如下: //1359:滑動視窗(pusu)//next單調佇列 #include<iostream

18.12.16 滑動視窗單調佇列

描述 給定一個長度為n(n<=10^6)的陣列。有一個大小為k的滑動視窗從陣列的最左端移動到最右端。你可以看到視窗中的k個數字。視窗每次向右滑動一個數字的距離。 下面是一個例子: 陣列是 [1 3 -1 -3 5 3 6 7], k = 3。