POJ 2823 單調佇列

_rabbit發表於2014-05-12
Sliding Window
Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 36469   Accepted: 10803
Case Time Limit: 5000MS

Description

An array of size n ≤ 106 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

Source


求每一個長度為k的區間的最大值,最小值,把它們都輸出來。

與上面的那道很類似,用兩個單調佇列,一個遞增,一個遞減,然後從左向右掃描一遍即可。

POJ G++ tle,C++勉強ac,卡時較嚴重。

程式碼:

/* ***********************************************
Author :_rabbit
Created Time :2014/5/12 23:07:15
File Name :20.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
int a[1001000],que1[1001000],que2[1001000],ans1[1001000],ans2[1000100];
int main()
{
     //freopen("data.in","r",stdin);
     //freopen("data.out","w",stdout);
     int n,k;
	 while(~scanf("%d%d",&n,&k)){
		 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		 int head=1,end=k,front1=0,tail1=0,front2=0,tail2=0;
		 for(int i=1;i<=k;i++){
			 while(front1<tail1&&a[que1[tail1-1]]>a[i])tail1--;//遞增序列
			 que1[tail1++]=i;
			 while(front2<tail2&&a[que2[tail2-1]]<a[i])tail2--;//遞減序列
			 que2[tail2++]=i;
		 }
		 ans1[1]=a[que1[front1]];ans2[1]=a[que2[front2]];
		 for(int i=k+1;i<=n;i++){
			 head=i-k+1;end=i;
			 while(front1<tail1&&a[que1[tail1-1]]>a[i])tail1--;
			 que1[tail1++]=i;
			 while(que1[front1]<head)front1++;
			 ans1[i-k+1]=a[que1[front1]];
			 while(front2<tail2&&a[que2[tail2-1]]<a[i])tail2--;
			 que2[tail2++]=i;
			 while(que2[front2]<head)front2++;
			 ans2[i-k+1]=a[que2[front2]];
		 }
		 for(int i=1;i<=n-k+1;i++)printf("%d%c",ans1[i],i==n-k+1?'\n':' ');
		 for(int i=1;i<=n-k+1;i++)printf("%d%c",ans2[i],i==n-k+1?'\n':' ');
	 }
     return 0;
}


相關文章