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小的时候,如果存在关系,
不会为答案,因为如果aj是第一个小于ai的,aj作为答案。aj比ai大,
也不会是答案。所以在从左到右遍历的时候维护一个单调栈,加入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;
}