有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 (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("\n");
//system("pause");
return 0;
}