【codeforces 548D】Mike and Feet

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard 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 strength of 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 × 105), the number of bears.

The second line contains n integers separated by space, a1, a2, …, an (1 ≤ ai ≤ 109), 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.

Examples
input
10
1 2 3 4 5 4 3 2 1 6
output
6 4 4 3 3 2 2 1 1 1

【题目链接】:http://codeforces.com/contest/548/problem/D

【题解】

说一个暴力的思路;
枚举、假设第i个数字作为一段连续中的最小的数字;
看看往左能多远、往右能多远(这个第i个数字要满足是最小的);
记为l和r
记长度为L;
则长度为L的连续段里面包括这个最小值;
同时长度为L-1,L-2,…1的连续段里面的最小值肯定也包括这么一个(但不一定是最小值里面的最大值);
设ans[L]为长度为L的连续段的最小值的最大值;
则必有ans[L]<=ans[L-1]<=ans[L-2]….
因为长度越小,一段区间里面的最小值的最大值就能越大(也可能相等).
回到上面;
我们在获得l和r之后计算出了L,然后要更新ans数组了;
则我们可以只尝试更新ans[L];
如果ans[L]比a[i]来得大.那么ans[L-1],ans[L-2]也不可能用a[i]来更新
因为ans[L]比a[i]大..则必然有一个区间内ans[L-1],ans[L-2]能够取得和ans[L]一样的值,则可知ans[L-1],ans[L-2]也不用更新..
如果ans[L]更新了,则也不用着急;
最后再逆序i=n->1 ans[i]= max(ans[i],ans[i+1])一下就好;
注意ans[L]能取到的值,ans[L-1]肯定也能取到!!
因为每个数字都这样枚举过。所以肯定每个数都考虑在ans数组里了;
如果L=4,那么L=2的情况也包含在内了,因为最后那个逆序的更新。。
而L=3,就代表L=4的情况不能用当前这第i个数字更新,这个程序也不会错解.
就是这么理解吧.
可以用一个单调队列先搞出l[i],r[i]分别表示最右边但在i左边的小于第i个数字的位置,以及最左边的但在i右边的小于第i个数字的位置.

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int MAXN = 2e5+10;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);

int n,a[MAXN],ans[MAXN],l[MAXN],r[MAXN];
stack <int> sta;

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    rei(n);
    rep1(i,1,n)
        rei(a[i]);
    rep1(i,1,n)
    {
        while (!sta.empty() && a[sta.top()]>= a[i]) sta.pop();
        if (sta.empty())
            l[i] = 0;
        else
            l[i] = sta.top();
        sta.push(i);
    }
    while (!sta.empty()) sta.pop();
    rep2(i,n,1)
    {
        while (!sta.empty() && a[sta.top()]>= a[i]) sta.pop();
        if (sta.empty())
            r[i] = n+1;
        else
            r[i] = sta.top();
        sta.push(i);
    }
    rep1(i,1,n)
    {
        int len = r[i]-l[i]-1;
        ans[len] = max(ans[len],a[i]);
    }
    rep2(i,n-1,1)
        ans[i] = max(ans[i+1],ans[i]);
    rep1(i,1,n)
    {
        printf("%d",ans[i]);
        if (i==n)
            puts("");
        else
            putchar(' ');
    }
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626784.html