单调栈与单调队列入门例题

单调栈

HDU 1506


 用栈来维护当前位置所能向左边和右边拓展的长度

#include <iostream>
#include <cstring>
//#pragma GCC optimize(2)
#include <time.h>
#include <queue>
#include <cmath>
#include <stack>
using namespace std;
#define maxn 100005
#define inf 1e18
#define eps 0.00001
typedef long long ll;
const ll mod = 1e9+7;

ll n,arr[maxn],L[maxn],R[maxn];

int main()
{

    while(cin >> n && n)
    {
        ll ans = 0;
        memset(L,0,sizeof(L));
        memset(R,0,sizeof(R));

        for(ll i = 1; i <= n; i++)
            cin >> arr[i];

        stack<ll>A,B;

        for(ll i = 1; i <= n; i++)
        {
            while( !A.empty() && arr[ A.top() ] >= arr[i] )
            {
                A.pop();
            }

            if( A.size() != 0 )
                L[i] = A.top()+1;
            else
                L[i] = 1;

            A.push(i);

        }

        for(ll i = n; i >= 1; i--)
        {
            while( !B.empty() && arr[ B.top() ] >= arr[i] )
            {
                B.pop();
            }

            if( B.size() != 0 )
                R[i] = B.top()-1;
            else
                R[i] = n;

            B.push(i);

        }

        /*for(ll i = 1; i <= n; i++)
        {
            cout << L[i] << " " << R[i] << endl;
        }*/



        for(ll i = 1; i <= n; i++)
        {
            ans = max(ans,( R[i]-L[i] + 1 )*arr[i] );
        }

        cout << ans << endl;

    }

    return 0;
}

单调队列

POJ 2823


双端队列,队头维护在窗口范围内的最大值或最小值

#include <iostream>
//#include <cstring>
//#pragma GCC optimize(2)
#include<time.h>
#include <queue>
#include <cmath>
using namespace std;
#define maxn 10000005
#define inf 1e18
#define eps 0.00001
typedef long long ll;
const ll mod = 1e9+7;
//const double pi = acos(-1);

ll n,m,arr[maxn];

struct Why
{
    ll step,num;
    Why(ll a,ll b)
    {
        step = a;
        num = b;
    }
};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    //freopen("D:\\test1.in","w",stdout);
    //srand((int)time(0));

    cin >> n >> m;

    for(ll i = 1; i <= n; i++)
        cin >> arr[i];

    deque<Why>A;

    for(ll i = 1; i <= n; i++)
    {

        while( !A.empty() && A.back().num >= arr[i] )
        {
            A.pop_back();
        }

        while( !A.empty() && i - A.front().step >= m )
        {
            A.pop_front();
        }

        A.push_back( Why(i,arr[i]) );

        if(i >= m)
            cout << A.front().num << " ";
    }

    cout << endl;

    deque<Why>B;

    for(ll i = 1; i <= n; i++)
    {

        while( !B.empty() && B.back().num <= arr[i] )
        {
            B.pop_back();
        }

        while( !B.empty() && i - B.front().step >= m  )
        {
            B.pop_front();
        }


        B.push_back( Why(i,arr[i]) );

        if(i >= m)
            cout << B.front().num << " ";
    }

    cout << endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Whyckck/article/details/83783247