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("\n"); //system("pause"); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。