算法进阶指南:基本数据结构0x11 栈

1.包含min函数的栈 (Push,Pop,Getmin)

传送门

class MinStack {
public:
    /** initialize your data structure here. */
    int a[110]={(int)2e9},b[110]={(int)2e9};
    int sz=0;
    MinStack() {
        
    }
    
    void push(int x) {
        a[++sz]=x;
        b[sz]=min(b[sz-1],x);
    }
    
    void pop() {
        --sz;
    }
    
    int top() {
        return a[sz];
    }
    
    int getMin() {
        return b[sz];
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

2.Editor

传送门

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<list> 
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define se second 
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
#define INF 1e12
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=1e9+7;
const int N=1e6+10;
int a[N],b[N],sa,sb,s[N],mx[N]={-(int)1e9};
void solve()
{
	char op;
    int x;
    cin>>op;
    if(op=='I'){
        cin>>x;
        a[++sa]=x;
        s[sa]=s[sa-1]+x;
        mx[sa]=max(mx[sa-1],s[sa]);
    }
    else if(op=='D') {if(sa) --sa;}
    else if(op=='L') {if(sa) b[++sb]=a[sa--];}
    else if(op=='R'){
        if(sb){
            a[++sa]=b[sb--];
            s[sa]=s[sa-1]+a[sa];
            mx[sa]=max(mx[sa-1],s[sa]);
        }
    }
    else cin>>x,cout<<mx[x]<<endl;
}
int main()
{
//	#ifndef ONLINE_JUDGE
//		freopen("title.in","r",stdin);
//		freopen("title.out","w",stdout);
//	#endif
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
	cin>>_; 
	while(_--){
		solve();
	}
	return 0;
}

 3.进出栈序列问题

传送门

from math import factorial as fac
n=int(input())
print(fac(2*n)//fac(n)//fac(n)//(n+1))

4.Largest Rectangle in a Histogram 

传送门

 枚举每一个ai,若以ai为高度,计算它的左右最大宽度,即往左遍历找到第一个比ai小的,往右遍历找到第一个比ai小的,加起来就是最大宽度。

如果直接枚举的话复杂度最坏是n^2。考虑在找左边第一个比ai小的时候,如果存在关系a_{j-1}\geq a_{j}a_{j-1}不会为答案,因为如果aj是第一个小于ai的,aj作为答案。aj比ai大,a_{j-1}也不会是答案。所以在从左到右遍历的时候维护一个单调栈,加入ai的时候把大于等于ai的元素都弹出栈,这样每个元素最多被枚举两次。右边同理,反过来做一遍就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<list> 
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define se second 
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
#define INF 1e12
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=1e9+7;
const int N=1e5+10;
int a[N],l[N],st[N],sz;
void solve()
{
	int n;
	while(cin>>n,n){
		LL ans=0;
		rep(i,1,n+1) cin>>a[i];
		sz=0;
		rep(i,1,n+1){
			while(sz&&a[st[sz]]>=a[i]) --sz;
			l[i]=st[sz]+1;
			st[++sz]=i;
		}
		sz=0;
		per(i,n,0){
			int r=n;
			while(sz&&a[st[sz]]>=a[i]) --sz;
			if(sz) r=st[sz]-1;
			st[++sz]=i;
			ans=max(ans,1ll*a[i]*(r-l[i]+1));
		}
		cout<<ans<<endl;
	}
}
int main()
{
//	#ifndef ONLINE_JUDGE
//		freopen("title.in","r",stdin);
//		freopen("title.out","w",stdout);
//	#endif
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
	//cin>>_; 
	while(_--){
		solve();
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值