您的位置:首页 > Web前端

codeforces #305 547B B. Mike and Feet(单调栈)

2015-06-30 10:50 211 查看
题目链接:

点击打开链接

题目大意:

给出一个序列,一个区间的值取这个区间中最小的数的值,那么不同长度区间的最大区间的值

题目分析:

首先我们可以考虑这么一条性质,也就是如果存在一个点作为当前区间的值,那么它向左向右能扩展的最大距离,就是它能支配的最大区间,而长度小于这个区间的区间它也能支配,那么它延展的距离内满足所有的值不大于它,这正好满足单调栈的性质。利用单调栈扫两边,栈内保持单调递增,然后每次找到比当前点小的最近的点,取做延展的最远距离,然后反向扫一遍,最后利用每个单点的值修改对应最大区间长度的最大值,长度小的区间最大值一定不小于长度大的区间,所以ans[i-1] = max ( ans[i] , ans[i-1] )递推以下,就是最终答案了,算是单调栈的模板题了

代码如下:

用了stl,1A,继续呐喊stl大法好

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <stack>
#define PII pair<int,int>
#define x first
#define id second
#define MAX 200007

using namespace std;

int n;
int a[MAX];
int ans[MAX];
int l[MAX],r[MAX];
stack<PII> s;

int main ( )
{
    while ( ~scanf ( "%d" , &n ) )
    {
        memset ( ans , 0 , sizeof ( ans ) );
        for ( int i = 0 ; i < n ; i++ )
            scanf ( "%d" , &a[i] );
        //s.clear();
        while ( !s.empty() ) s.pop();
        l[0] = 0;
        s.push( make_pair ( a[0] , 0 ) );
        for ( int i = 1 ; i < n ; i++ )
        {
            while ( !s.empty() && s.top().x >= a[i] )
                s.pop();
            //cout << "YES : " << i  << endl;
            if ( !s.empty() ) l[i] = s.top().id + 1;
            else l[i] = 0;
            s.push ( make_pair ( a[i] , i ) );
        }
        //cout << "YES" << endl;
        //s.clear();
        while ( !s.empty() ) s.pop();
        r[n-1] = n-1;
        s.push ( make_pair ( a[n-1] , n-1 ) );
        for ( int i = n-2 ; i >= 0 ; i-- )
        {
            while ( !s.empty() && s.top().x >= a[i] )
                s.pop();
            if ( !s.empty() ) r[i] = s.top().id - 1;
            else r[i] = n-1;
            s.push ( make_pair ( a[i] , i ) );
        }
        for ( int i = 0 ; i < n ; i++ )
            ans[r[i]-l[i]+1] = max ( a[i] , ans [r[i]-l[i]+1] );
        for ( int i = n-1 ; i >= 1 ; i-- )
            ans[i] = max ( ans[i] , ans[i+1] );
        for ( int i = 1; i <= n ; i++ )
            printf ( "%d " , ans[i] );
        puts("");
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: