单调栈
对每个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();
}

京公网安备 11010502036488号