单调栈 单调队列

单调栈模版:

//求l,r内最大矩形面积:
//h[i]:[L[i],R[i]) 左开右闭,h[i]为区间的最小值
//L[i]:对于h[i]将栈内大于它的数都去掉,这些数不可能做为左端点,若栈为空则L[i]=0,否则L[i]=s.top()+1;
//R[i]:对于h[i]将栈内大于它都数都去掉,这些数不可能做为右端点,若栈为空则R[i]=n,否则R[i]=s.top();

#include "stack"
int h[N];
int L[N],R[N];
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n!=0)
    {
        for(int i=0;i<n;i++) ci(h[i]);
        stack<int> s;
        for(int i=0;i<n;i++){
            while(s.size()>0&&h[i]<=h[s.top()]) s.pop();
            if(s.empty()==1) L[i]=0;
            else L[i]=s.top()+1;
            s.push(i);
        }
        while(!s.empty()) s.pop();
        for(int i=n-1;i>=0;i--){
            while(s.size()>0&&h[i]<=h[s.top()]) s.pop();
            if(s.empty()==1) R[i]=n;
            else R[i]=s.top();
            s.push(i);
        }
        ll res=0;
        for(int i=0;i<n;i++)
            res=max(res,1ll*h[i]*(R[i]-L[i]));
        pl(res);
    }
    return 0;
}

//单调队列:
//(求连续区间极值):求a[i~i+k-1]的 min 与 max.
#include "deque"
int main()
{
    int n,k;
    deque<int> q;
    while(scanf("%d%d",&n,&k)==2)
    {
        if(q.size()>0) q.clear();
        for(int i=0;i<n;i++) ci(a[i]);
        for(int i=0;i<n;i++){//get min
            while(q.size()>0&&a[q.back()]>=a[i]) q.pop_back();
            q.push_back(i);
            if(i-k+1>=0){
                b[i-k+1]=a[q.front()];
                if(q.front()==i-k+1) q.pop_front();
            }
        }
        if(q.size()>0) q.clear();
        for(int i=0;i<n;i++){//get max
            while(q.size()>0&&a[q.back()]<=a[i]) q.pop_back();
            q.push_back(i);
            if(i-k+1>=0){
                c[i-k+1]=a[q.front()];
                if(q.front()==i-k+1) q.pop_front();
            }
        }
        for(int i=0;i<=n-k;i++) printf("%d%c",b[i],i==n-k?'\n':' ');
        for(int i=0;i<=n-k;i++) printf("%d%c",c[i],i==n-k?'\n':' ');
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/mj-liylho/p/9032230.html