[USACO09MAR]向右看齐Look Up(单调队列在线处理)

Posted jiamian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO09MAR]向右看齐Look Up(单调队列在线处理)相关的知识,希望对你有一定的参考价值。

https://www.luogu.org/problem/P2947

 

题目描述

Farmer John‘s N (1 <= N <= 100,000) cows, conveniently numbered 1..N, are once again standing in a row. Cow i has height Hi (1 <= Hi <= 1,000,000).
Each cow is looking to her left toward those with higher index numbers. We say that cow i ‘looks up‘ to cow j if i < j and Hi < Hj. For each cow i, FJ would like to know the index of the first cow in line looked up to by cow i.
Note: about 50% of the test data will have N <= 1,000.

输入描述:

* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains the single integer: Hi

输出描述:

* Lines 1..N: Line i contains a single integer representing the smallest index of a cow up to which cow i looks. If no such cow exists, print 0.

示例1

输入

6 
3 
2 
6 
1 
1 
2 

输出

3
3
0
6
6
0

说明

FJ has six cows of heights 3, 2, 6, 1, 1, and 2.
Cows 1 and 2 both look up to cow 3; cows 4 and 5 both look up to cow 6; and cows 3 and 6 do not look up to any cow.

 

找每个数右边第一个大于等于它的位置,并输出该位置,如果没有就输出0

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 #include <set>
10 #include <map>
11 #include <math.h>
12 const int INF=0x3f3f3f3f;
13 typedef long long LL;
14 const int mod=1e9+7;
15 //const int mod=1e8;
16 //const double PI=acos(-1);
17 const int maxn=1e5+10;
18 using namespace std;
19 //ios::sync_with_stdio(false);
20 //    cin.tie(NULL);
21 
22 int A[maxn]; 
23 int ans[maxn];
24 
25 int main()
26 
27     int n;
28     scanf("%d",&n);
29     for (int i=1;i<=n;i++)
30         scanf("%d",&A[i]);
31     vector<int> vt; 
32     vt.push_back(1);
33     int MIN=A[1];
34     for (int i = 2; i <= n; i++)
35     
36         if(A[i]>=MIN) 
37         
38             while (!vt.empty()) 
39             
40                 if (A[*(vt.end()-1)]<A[i])
41                 
42                     ans[*(vt.end()-1)]=i;
43                     vt.erase(vt.end()-1);
44                 
45                 else
46                     break;
47             
48             vt.push_back(i);
49         
50         else
51         
52             vt.push_back(i);
53             MIN=ans[i];
54         
55      
56     for (vector<int>::iterator it=vt.begin();it!=vt.end();it++) 
57     
58         ans[*it]=0;
59     
60     for (int i=1;i<=n;i++)
61         printf("%d\n",ans[i]);
62     return 0;
63 

 

 

其实上面的代码就用到了单调栈的思想

 

何为单调栈?
解释一下:
单调栈类似单调队列,这道题中要运用到单调栈。
如下:
令f[i]为向右看齐的人的标号
6 3 2 6 1 1 2
f分别为 3 3 0 6 6 0
首先,最后一个人必然没有向右看齐的人的编号
先将最右边的人加入栈
接着,我们发现1,1比2小,先加入栈,当前f值为6
接着,又来了一个1,发现1=1,弹出1,接着发现1<2,则将1加进栈,当前f值为6
接着,来了一个6,6>2,弹出2,当前f值为0
接着,来了一个2,2<6,加入2,当前f值为3
最后,来了一个3,3>2,弹出2,将3加入栈,当前f值为3
最后的栈中有3和6
最后的答案就是3 3 0 6 6 0
每次只在栈中存数字标号,进来一个数,就把小于等于他的数全部弹出,若剩下有数,则答案是剩下的数,否则答案是0
为什么?
因为:
若x小于当前数,x不会成为答案。
这就是单调栈的用法

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <math.h>
13 const int INF=0x3f3f3f3f;
14 typedef long long LL;
15 const int mod=1e9+7;
16 const int maxn=1e5+10;
17 using namespace std;
18 
19 int A[maxn]; 
20 int ans[maxn];
21 stack<int> sk; 
22 
23 int main()
24 
25     int n;
26     scanf("%d",&n);
27     for (int i=1;i<=n;i++)
28         scanf("%d",&A[i]);
29     for(int i=n;i>=1;i--)
30     
31         while(!sk.empty()&&A[sk.top()]<=A[i])
32             sk.pop();
33         if(!sk.empty())
34             ans[i]=sk.top();
35         else
36             ans[i]=0;
37         sk.push(i);
38     
39     for (int i=1;i<=n;i++)
40         printf("%d\n",ans[i]);
41     return 0;
42 

 

 

以上是关于[USACO09MAR]向右看齐Look Up(单调队列在线处理)的主要内容,如果未能解决你的问题,请参考以下文章

[USACO09MAR]向右看齐Look Up(单调队列在线处理)

单调队列————[USACO09MAR]向右看齐Look Up

P2947 [USACO09MAR]向右看齐Look Up

luogu P2947 [USACO09MAR]向右看齐Look Up 题解

洛谷P2947 [USACO09MAR]仰望Look Up

[USACO09MAR]Look Up