[USACO09MAR]向右看齐Look Up(单调栈、在线处理)
https://www.luogu.org/problem/P2947
题目描述
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
输入
输出
说明
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
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const int maxn=1e5+;
using namespace std; int A[maxn];
int ans[maxn]; int main()
{
int n;
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&A[i]);
vector<int> vt;
vt.push_back();
int MIN=A[];
for (int i = ; i <= n; i++)
{
if(A[i]>=MIN)
{
while (!vt.empty())
{
if (A[*(vt.end()-)]<A[i])
{
ans[*(vt.end()-)]=i;
vt.erase(vt.end()-);
}
else
break;
}
vt.push_back(i);
}
else
{
vt.push_back(i);
MIN=ans[i];
}
}
for (vector<int>::iterator it=vt.begin();it!=vt.end();it++)
{
ans[*it]=;
}
for (int i=;i<=n;i++)
printf("%d\n",ans[i]);
return ;
}
其实上面的代码就用到了单调栈的思想
何为单调栈?
解释一下:
单调栈类似单调队列,这道题中要运用到单调栈。
如下:
令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不会成为答案。
这就是单调栈的用法
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const int maxn=1e5+;
using namespace std; int A[maxn];
int ans[maxn];
stack<int> sk; int main()
{
int n;
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&A[i]);
for(int i=n;i>=;i--)
{
while(!sk.empty()&&A[sk.top()]<=A[i])
sk.pop();
if(!sk.empty())
ans[i]=sk.top();
else
ans[i]=;
sk.push(i);
}
for (int i=;i<=n;i++)
printf("%d\n",ans[i]);
return ;
}
[USACO09MAR]向右看齐Look Up(单调栈、在线处理)的更多相关文章
- P2947 [USACO09MAR]向右看齐Look Up--单调栈
单调栈真的很好用呢! P2947 [USACO09MAR]向右看齐Look Up 题目描述 Farmer John's N (1 <= N <= 100,000) cows, conven ...
- luogu P2947 [USACO09MAR]向右看齐Look Up |单调队列
题目描述 Farmer John's N (1 <= N <= 100,000) cows, conveniently numbered 1..N, are once again stan ...
- BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)
BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...
- DP的各种优化(动态规划,决策单调性,斜率优化,带权二分,单调栈,单调队列)
前缀和优化 当DP过程中需要反复从一个求和式转移的话,可以先把它预处理一下.运算一般都要满足可减性. 比较naive就不展开了. 题目 [Todo]洛谷P2513 [HAOI2009]逆序对数列 [D ...
- HUID 5558 Alice's Classified Message 后缀数组+单调栈+二分
http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做 ...
- HDU - 5033 Building (单调栈+倍增)
题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...
- 2019 计蒜之道 复赛 D. “星云系统”(单调栈)
VIPKID 是在线少儿英语教育平台,网络稳定是在线教育课程质量的红线,VIPKID 为此推出了全球最稳定的教育网络系统 -- "星云系统".星云系统目前建立了覆盖全球 3535 ...
- 2019牛客暑期多校训练营(第一场) - A - Equivalent Prefixes - 单调栈
A - Equivalent Prefixes - 单调栈 题意:给定两个n个元素的数组a,b,它们的前p个元素构成的数组是"等价"的,求p的最大值."等价"的 ...
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
随机推荐
- LARGE_INTEGER 64位的输出格式
%016I64x 第一个016是指当最左边无数据时用00填充:后面的I64x是__int64的前缀要求格式十六进制输出.
- AD走圆弧走线
美式键盘: “shift + 空格”
- Linux终端命令行的常用快捷键
history 显示命令历史列表 ↑(Ctrl+p) 显示上一条命令 ↓(Ctrl+n) 显示下一条命令 !num 执行命令历史列表的第num条命令 !! 执行上一条命令 !?string? 执行含有 ...
- BZOJ:2186: [Sdoi2008]沙拉公主的困惑
问题:可能逆元不存在吗? 题解: Gcd(a,b)==Gcd(b,a-b); 从数据范围可以看出应该求M!的欧拉函数: 然后通过Gcd转化过去 一开始没想到 #include<iostream& ...
- (1) JVM内存管理:内存模型
引子 一段简单的代码结果引发疑问,==到底比较的是什么?equals呢? public static void main(String args[]){ String s1="abc&quo ...
- meta标签小结
1.手机页面所需: <meta name="viewport" content="width=device-width,initial-scale=1.0,mini ...
- CF1217A Creating a Character
You play your favourite game yet another time. You chose the character you didn't play before. It ha ...
- 51nod 1393:0和1相等串
1393 0和1相等串 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等. I ...
- Arduino串口的一些高级用法
1.配置串口通信数据位.校验位.停止位通常我们使用Serial.begin(speed)来完成串口的初始化,这种方式,只能配置串口的波特率.而使用Serial.begin(speed, config) ...
- 19 01 13 JQery 加载 选择器 样式操作
在Javascript 中应该用下方法经行编辑 <script type="text/javascript" src="js/jquery-1.12.4.min ...