poj2823单调对列和poj3250单调栈


poj2823
Sliding Window
Time Limit: 12000MS Memory Limit: 65536K
Total Submissions: 52190 Accepted: 14949
Case Time Limit: 5000MS

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 positionMinimum valueMaximum value
[1  3  -1] -3  5  3  6  7 -13
 1 [3  -1  -3] 5  3  6  7 -33
 1  3 [-1  -3  5] 3  6  7 -35
 1  3  -1 [-3  5  3] 6  7 -35
 1  3  -1  -3 [5  3  6] 7 36
 1  3  -1  -3  5 [3  6  7]37

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

单调对列(deque),(后进前出),对列里的数据是有序的(递增或递减),遇到要压入的数,如果不满足单调性,就一直弹出队尾元素,再压入。注意这样保存的是,q存的是下标;

#include<iostream>
#include<cstdio>
using namespace std;
int a[1000005];
int q[1000005];
int main(){
	
	int n,l;
	scanf("%d%d",&n,&l);
		int head=0,end=1;
		for (int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		q[end]=1;
		for (int i=1;i<=n;i++){
			if (head<end&&i-q[head+1]+1>l) head++;
			while(head<end&&a[q[end]]>=a[i]){
				--end;
			}
			q[++end]=i;
			//cout<<"t"<<q[head]<<" "<<q[end]<<endl;
			if (i>l){
				printf(" %d",a[q[head+1]]);
			}
			else if(i==l) printf("%d",a[q[head+1]]);
		}
		printf("\n");
		
		head=0;end=1;
		q[end]=1;
		for (int i=1;i<=n;i++){
			if (head<end&&i-q[head+1]+1>l) head++;
			while(head<end&&a[q[end]]<=a[i]){
				--end;
			}
			q[++end]=i;
			//cout<<"t"<<q[head]<<" "<<q[end]<<endl;
			if (i>l){
				printf(" %d",a[q[head+1]]);
			}
			else if(i==l) printf("%d",a[q[head+1]]);
		}
		printf("\n");
	//}
}

单调栈

Bad Hair Day
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 16654 Accepted: 5601

Description

Some of Farmer John's N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-conscious about her messy hairstyle, FJ wants to count the number of other cows that can see the top of other cows' heads.

Each cow i has a specified height hi (1 ≤hi ≤ 1,000,000,000) and is standing in a line of cows all facing east (to the right in our diagrams). Therefore, cowi can see the tops of the heads of cows in front of her (namely cows i+1, i+2, and so on), for as long as these cows are strictly shorter than cowi.

Consider this example:

        =
=       =
=   -   =         Cows facing right -->
=   =   =
= - = = =
= = = = = =
1 2 3 4 5 6 

Cow#1 can see the hairstyle of cows #2, 3, 4
Cow#2 can see no cow's hairstyle
Cow#3 can see the hairstyle of cow #4
Cow#4 can see no cow's hairstyle
Cow#5 can see the hairstyle of cow 6
Cow#6 can see no cows at all!

Let ci denote the number of cows whose hairstyle is visible from cowi; please compute the sum of c1 throughcN.For this example, the desired is answer 3 + 0 + 1 + 0 + 1 + 0 = 5.

Input

Line 1: The number of cows, N.
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i.

Output

Line 1: A single integer that is the sum of c 1 through cN.

Sample Input

6
10
3
7
4
12
2

Sample Output

5


就是求每个数前面有多少个连续比他小的数,遇到>=他高的就停止。

求总共看到的人头数,转化为每个人被看到的次数,这样问题就可以用单调栈求解,该栈是递减的,仔细想一想如果当前来的数比栈顶小,那么能被栈内所有人看到,ans+=stack.size(),否则,弹出栈内比他小的所有人,并且把它压栈,因为比他小的人都被他挡住了,然后代码简单就不贴了这道题思路转化很重要


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值