【Psychos in a Line】【CodeForces - 320D】(单调栈)

题目:

There are n psychos standing in a line. Each psycho is assigned a unique integer from 1 to n. At each step every psycho who has an id greater than the psycho to his right (if exists) kills his right neighbor in the line. Note that a psycho might kill and get killed at the same step.

You're given the initial arrangement of the psychos in the line. Calculate how many steps are needed to the moment of time such, that nobody kills his neighbor after that moment. Look notes to understand the statement more precise.

Input

The first line of input contains integer n denoting the number of psychos, (1 ≤ n ≤ 105). In the second line there will be a list of n space separated distinct integers each in range 1 to n, inclusive — ids of the psychos in the line from left to right.

Output

Print the number of steps, so that the line remains the same afterward.

Examples

Input

10
10 9 7 8 6 5 3 4 2 1

Output

2

Input

6
1 2 3 4 5 6

Output

0

Note

In the first sample line of the psychos transforms as follows: [10 9 7 8 6 5 3 4 2 1]  →  [10 8 4]  →  [10]. So, there are two steps.

解题报告:题意:就是给定一行精神病人,他们每个人都有自己的某种数值,如果当前位置的右侧的人的数值小于它,那么它会杀死它右侧的那个人,且存在连续杀性质(能够将这个性质在一个时间单位下进行传递)

思路就是,读懂题目之后,会发现这是类似于单调栈的操作,咱们都要将当前位置的右侧的比它小的数给抹去,即找到第一个比他大的位置。不停的操作,直至栈只剩一个winer。中间的变量step,要记录每次需要耗费的时间,看看每次最多的效益。

ac代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
typedef long long ll;

struct node{
	int data;
	int step;
};

int main()
{
	int n;
	int num[100100];
	stack<struct node> que;
	while(scanf("%d",&n)!=EOF)
	{
		while(!que.empty()) que.pop();
		for(int i=0;i<n;i++)
		{
			scanf("%d",&num[i]);
		}
		int i=0;
		while(i<(n-1)&&num[i]<=num[i+1]) i++;
		node tmp;
		tmp.data=num[i++];
		tmp.step=0;//找到第一个高的。 
		que.push(tmp);
		int ans=0;
		int m;
		for(;i<n;i++)
		{
			node p=que.top();
			if(num[i]<p.data)
				tmp.data=num[i],tmp.step=1;
			else
			{
				m=0;
				while(!que.empty())
				{
					tmp=que.top();
					if(tmp.data<num[i])
					{
						m=max(m,tmp.step);
						que.pop();
					}
					else
						break;
				}
				tmp.data=num[i];
				if(que.empty())
					tmp.step=0;
				else
					tmp.step=m+1;	
			}
			que.push(tmp);
			ans=max(ans,tmp.step);
		}
		printf("%d\n",ans);
	 } 
} 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值