CF #305(Div.2) D. Mike and Feet(数学推导)

D. Mike and Feet
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Mike is the president of country What-The-Fatherland. There are n bears living in this country besides Mike. All of them are standing in a line and they are numbered from 1 to n from left to right. i-th bear is exactly ai feet high.

A group of bears is a non-empty contiguous segment of the line. The size of a group is the number of bears in that group. The strengthof a group is the minimum height of the bear in that group.

Mike is a curious to know for each x such that 1 ≤ x ≤ n the maximum strength among all groups of size x.

Input

The first line of input contains integer n (1 ≤ n ≤ 2 × 10^5), the number of bears.

The second line contains n integers separated by space, a1, a2, ..., an (1 ≤ ai ≤ 10^9), heights of bears.

Output

Print n integers in one line. For each x from 1 to n, print the maximum strength among all groups of size x.

Sample test(s)
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<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 const int M = 2e5 + 10 ;
 5 int l[M] , r[M] , a[M] ;
 6 int b[M] ;
 7 int n ;
 8 int main ()
 9 {
10    // freopen ("a.txt" , "r" , stdin ) ;
11     scanf ("%d" , &n) ;
12     for (int i = 1 ; i <= n ; i ++) scanf ("%d" , &a[i]) ;
13     a[0] = 0 ; a[n + 1] = 0 ;
14     memset (b , - 1 , sizeof(b)) ;
15     for (int i = 1 ; i <= n ; i ++) {
16         l[i] = i ;
17         while (a[l[i] - 1] >= a[i]) l[i] = l[l[i] - 1] ;
18     }
19     for (int i = n ; i >= 1 ; i --) {
20         r[i] = i ;
21         while (a[r[i] + 1] >= a[i]) r[i] = r[r[i] + 1] ;
22     }
23     for (int i = 1 ; i <= n ; i ++) {
24         int id = r[i] - l[i] + 1 ;
25         b[id] = std::max (b[id] , a[i]);
26     }
27     for (int i = n ; i >= 2 ; i --) {
28         if (b[i - 1] < b[i] ) b[i - 1] = b[i] ;
29     }
30     for (int i = 1 ; i <= n ; i ++) printf ("%d%c" , b[i] , i == n ? '
' : ' ') ;
31     return 0 ;
32 }
33 /*10
34 1 2 3 4 5 4 3 2 1 6
35 */
View Code
  1. 最质补的想法,我们先考虑a[i]能影响的区间大小为w[i],(另b[i] 为长度为i的区间的最小的最大值)

for i = 1 to n

  for j = 1 to w[i]

    b[j] = max (b[j] , a[i]);

  end

end

这样最坏情况下O(n^n),显然tle.

通过yy可以发现,区间大的可以跟新区间小的,so:

for i = 1 to n 

  b[w[i]] = max (b[w[i]] , a[i]);

end

for i = n to 2

  if (b[i - 1] < b[i] )   b[i - 1] = b[i] ;

end

这样就变为O(n)了。

  2.第二个要解决的问题时我们怎样在O(n)内求出w[i] ?

令w[i] = r[i] - l[i] ;

令r[i] , l[i]分别保存a[i]所能影响大的最右 和 最左。

这样在已知l[i]时,我们便可以在O(1)时间内求出l[i + 1]了。

原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4537468.html