51nod 1437:迈克步 单调栈基础题

题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
51nod 1437:迈克步 单调栈基础题 收藏
51nod 1437:迈克步 单调栈基础题 取消关注

有n只熊。他们站成一排队伍,从左到右依次1到n编号。第i只熊的高度是ai。

一组熊指的队伍中连续的一个子段。组的大小就是熊的数目。而组的力量就是这一组熊中最小的高度。

迈克想知道对于所有的组大小为x(1 ≤ x ≤ n)的,最大力量是多少。


Input
单组测试数据。
第一行有一个整数n (1 ≤ n ≤ 2×10^5),表示熊的数目。
第二行包含n个整数以空格分开,a1, a2, ..., an (1 ≤ ai ≤ 10^9),表示熊的高度。
Output
在一行中输出n个整数,对于x从1到n,输出组大小为x的最大力量。
Input示例
10
1 2 3 4 5 4 3 2 1 6
Output示例
6 4 4 3 3 2 2 1 1 1

之前的POJ 2796做过了之后,这个也就变得基础了。记录区间的长度,求区间的最小值,再从后往前,求最大值。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

#define N 300001

int a[N], lef[N], stack[N], top;
long long sum[N],ans[N];

int main()
{
	//freopen("i.txt", "r", stdin);
	//freopen("o.txt", "w", stdout);

	int i, j, n, len;
	int ll, rr;

	scanf("%d", &n);
	memset(sum, 0, sizeof(sum));
	for (i = 1; i <= n; i++)
	{
		scanf("%d", a + i);
		sum[i] = sum[i - 1] + a[i];
	}
	++n;
	fill(ans, ans + n, 0);
	a[n] = -1;
	top = 0;
	for (i = 1; i <= n; i++)
	{
		if (i == n - 1)
		{
			i++;
			i--;
		}
		//单调递减栈,从栈顶元素到栈底元素,值单调递减
		if (top == 0 || a[i] > a[stack[top - 1]])//如果当前元素的值大于栈顶的值,就将元素的值插入到栈中
		{
			stack[top++] = i;
			lef[i] = i;
			continue;
		}
		if (a[i] == a[stack[top - 1]])
			continue;
		while (top >= 1 && a[i] < a[stack[top - 1]])//如果当前元素的值小于栈顶元素,那么这时总结计算值,可能会是最大值
		{
			--top;

			len = i - 1 - (lef[stack[top]] - 1);
			if (a[stack[top]] > ans[len])
			{
				ll = lef[stack[top]];
				rr = i - 1;
				ans[len] = a[stack[top]];
			}
		}
		lef[i] = lef[stack[top]];
		stack[top++] = i;
	}

	for (i = n - 1; i >= 1; i--)
	{
		ans[i] =  max(ans[i], ans[i + 1]);
	}
	for (i = 1; i <= n - 1; i++)
	{
		if (i == 1)
		{
			printf("%lld", ans[i]);
		}
		else
		{
			printf(" %lld", ans[i]);
		}
	}
	printf("
");
	//system("pause");
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。