http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1437
题目来源:
CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80
难度:5级算法题
收藏
关注
有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
和上一题类似,根据元素得出对应区间的最值。
每个元素都对应着在一些区间里是最小值,我们不妨找到以每一个元素为最小值的最大区间,这个大区间所有包含此元素的子区间的力量显然也是这个元素。
1 #include <iostream> 2 #include<algorithm> 3 #include<stack> 4 #include<cstdio> 5 using namespace std; 6 typedef long long LL; 7 const int MAX = 200005; 8 int a[MAX], l[MAX], r[MAX], f[MAX]; 9 int _() { 10 int x = 0, c = getchar(); 11 while (c<48)c = getchar(); 12 while (c>47)x = x * 10 + c - 48, c = getchar(); 13 return x; 14 } 15 void _(int x) { 16 static int stk[32], stp = 0; 17 if (!x)putchar(48); 18 while (x)stk[stp++] = x % 10, x /= 10; 19 while (stp)putchar(stk[--stp] + 48); 20 putchar(32); 21 } 22 int main() 23 { 24 int N, i, j, k; 25 scanf("%d", &N); 26 for (i = 1;i <= N;++i) { 27 //scanf("%d", a + i); 28 a[i] = _(); 29 l[i] = r[i] = i; 30 } 31 for (i = 1,j=N;i <= N;++i,--j) { 32 while (l[i] != 1 && a[i] <= a[l[i] - 1]) 33 l[i] = l[l[i] - 1]; 34 while (r[j] != N&&a[j] <= a[r[j] + 1]) 35 r[j] = r[r[j] + 1]; 36 } 37 for (i = 1;i <= N;++i) 38 f[r[i] - l[i] + 1] = max(f[r[i]-l[i]+1],a[i]); 39 for (i = N - 1;i >= 1;--i) 40 f[i] = max(f[i], f[i + 1]); 41 for (i = 1;i < N;++i) _(f[i]);//printf("%d ", f[i]); 42 printf("%d\n", f[N]); 43 //system("pause"); 44 return 0; 45 }