【codeforces 548D】Mike and Feet

来源:互联网 发布:淘宝子账号怎么添加 编辑:程序博客网 时间:2024/06/06 09:40

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;}
0 0
原创粉丝点击