单调栈
对每个i求它最左和最右可以延伸到哪,然后维护这个延伸区间*i的高度的最大值即是答案
#include <iostream> #include <cstring> #include <cmath> #include <cstdio> #include <cstdlib> #include <algorithm> #include <map> #include <vector> #include <queue> #include <set> using namespace std; #define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++) #define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--) #define mst(v,s) memset(v,s,sizeof(v)) #define pb push_back #define IOS ios::sync_with_stdio(false) #define int long long #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f typedef long long ll; const int N=1e6+5; int n; int a[N],b[N]; int l[N],r[N]; vector <int > sta; void solve() { //右边,看最右延伸到哪 _for(i,1,n) { if( sta.empty() || b[i] >= b[sta.back()] ) { sta.pb(i); } else { while( !sta.empty() && b[i] < b[sta.back()] ) { r[sta.back()]=i-1; sta.pop_back(); } sta.pb(i); } } //栈里剩余元素说明可以延伸到n while( !sta.empty() ) { r[sta.back()]=n,sta.pop_back(); } //左边,看最左延伸到哪 _rep(i,n,1) { if( sta.empty() || b[i] >= b[sta.back()] ) { sta.pb(i); } else { while( !sta.empty() && b[i] < b[sta.back()] ) { l[sta.back()]=i+1; sta.pop_back(); } sta.pb(i); } } //栈里剩余元素说明可以延伸到1 while( !sta.empty() ) l[sta.back()]=1,sta.pop_back(); ll ans=0; _for(i,1,n) ans=max(ans , b[i]*(a[r[i]]-a[l[i]-1]));//左右延伸区间的长度 * 高 cout<<ans<<endl; } signed main() { ///!!! // freopen("data.txt","r",stdin); //!!! IOS; cin>>n; _for(i,1,n) { cin>>a[i]; a[i]=a[i-1]+a[i]; } _for(i,1,n) cin>>b[i]; solve(); }