[51nod1102]面積最大的矩形(單調棧||預處理)
阿新 • • 發佈:2017-11-04
return 棧模板 模板題 type its 長度 bit -- blog
題意:求序列上某區間最小值乘區間長度的最大值。
解題關鍵:很早就在《挑戰程序設計競賽》中見過了,單調棧模板題,註意彈棧時如何處理後面的元素。
法一:單調棧
#include<bits/stdc++.h> using namespace std; typedef long long ll; stack<int>s; ll a[50002]; int main(){ int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i];a[n]=-1; ll ans=0,tmp;for(int i=0;i<=n;i++){ if(s.empty()||a[i]>a[s.top()]) s.push(i); else if(a[i]<a[s.top()]){ while(!s.empty()&&a[i]<a[s.top()]){ tmp=s.top(); s.pop(); ans=max(ans,1ll*(i-tmp)*a[tmp]); } s.push(tmp); a[tmp]=a[i]; } } cout<<ans<<"\n"; return 0; }
法二:預處理,向左向右到達的範圍。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll a[50002],l[50002],r[50002]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++){ int k=i-1; while(a[k]>=a[i]){ k=l[k]-1; } l[i]=k+1; } for(int i=n;i>=1;i--){ int k=i+1; while(a[k]>=a[i]){ k=r[k]+1; } r[i]=k-1; } ll ans=0; for(int i=1;i<=n;i++){ ans=max(ans,(r[i]-l[i]+1)*a[i]); } cout<<ans<<"\n"; return 0; }
[51nod1102]面積最大的矩形(單調棧||預處理)