Mike and Feet CodeForces - 548D(单调栈)

题意:
给定一组长度为n的序列a[1],a[2]…a[n](n<=2e5,a[i]<=1e9),现在对于任意一个区间长度len(1<=len<=n),要求长度为len的连续子序列中最小值的最大值是多少,比如一个序列n=5,序列元素为2,3,6,4,1,那么当长度为2时答案就是4,即子序列{a[3],a[4]}中的最小值
思路:
1.求出每个数作为最小值的最大区间(求出这个数两边比它大的最近的数的坐标)
2.从后往前遍历,如果ans[i]

#include
#include
#include
#include
#include
using namespace std;
const int N=2e5+10;
int a[N];
int x[N];
int y[N];
int ans[N];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	stack<int> s;
	for(int i=1;i<=n;i++)
	{
		while(s.size()&&a[s.top()]>=a[i]) s.pop();
		if(s.size()) x[i]=s.top();
		s.push(i);
	}
	stack<int> ss;
	for(int i=n;i>=1;i--)
	{
		while(ss.size()&&a[ss.top()]>=a[i]) ss.pop();
		if(ss.size()) y[i]=ss.top();
		else y[i]=n+1;
		ss.push(i);
	}
	for(int i=1;i<=n;i++)
	{
		ans[y[i]-x[i]-1]=max(ans[y[i]-x[i]-1],a[i]);
	}
	for(int i=n-1;i>=1;i--)
	{
		if(ans[i]<ans[i+1]) ans[i]=ans[i+1];
	}
	for(int i=1;i<=n;i++)
	{
		if(i==1) printf("%d",ans[i]);
		else printf(" %d",ans[i]);
	}
	printf("\n");
}

你可能感兴趣的:(单调栈)