链接:https://ac.nowcoder.com/acm/contest/884/C
来源:牛客网
时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
Your are given two sequences a1…na_{1 \dots n}a1…n and b1…nb_{1 \dots n}b1…n .You need to answer max1≤l≤r≤n{min(al…r)×sum(bl…r)}\displaystyle \max_{1 \le l \le r \le n} \{min(a_{l \dots r}) \times sum(b_{l \dots r})\}1≤l≤r≤nmax{min(al…r)×sum(bl…r)} 。
Where min(a) means the minimal value of every element of sequence a, sum(a) means the sum of every element of sequence a .
输入描述:
The first line contains an integer n .
The second line contains n integers meaning a1…na_{1 \dots n}a1…n .
The third line contains n integers meaning b1…nb_{1 \dots n}b1…n .
输出描述:
An integer meaning the answer.
示例1
输入
复制
3 1 -1 1 1 2 3
输出
复制
3
备注:
For all test datas, 1≤n≤3×106,−106≤ai,bi≤1061 \leq n \leq 3 \times 10^6,-10^6 \leq a_i,b_i \leq 10^61≤n≤3×106,−106≤ai,bi≤106.
思路:通过以以每个A[i]为最小值所能扩展的区间,然后在此区间内选最大的B数组和,a数组扩展区间可以通过两次单调栈求出,区间和最大可以通过线段树或ST表求出,注意A[i]的正负要分类讨论
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
//typedef __int128 bll;
const ll maxn = 3e6+100;
const ll mod = 1e9+7;
const ld pi = acos(-1.0);
const ll inf = 1e18;
const ld eps = 1e-5;
const ld e = exp(1);
ll n,a[maxn],b[maxn],ans,preb[maxn],treema[maxn<<2],treemi[maxn<<2];
struct nodea
{
ll l,r;
}arra[maxn];
void build(ll now,ll l,ll r)
{
if(l == r)
{
treema[now] = preb[l];
treemi[now] = preb[l];
return ;
}
ll mid = (l+r)/2;
build(now*2,l,mid);
build(now*2+1,mid+1,r);
treema[now] = max(treema[now*2],treema[now*2+1]);
treemi[now] = min(treemi[now*2],treemi[now*2+1]);
return ;
}
ll queryma(ll now,ll l,ll r,ll a,ll b)
{
if(a <= l && b >= r)
{
return treema[now];
}
ll mid = (l+r)/2;
ll res = -inf;
if(a <= mid)
res = max( res,queryma(now*2,l,mid,a,b) );
if(b >= mid+1)
res = max( res,queryma(now*2+1,mid+1,r,a,b) );
return res;
}
ll querymi(ll now,ll l,ll r,ll a,ll b)
{
if(a <= l && b >= r)
{
return treemi[now];
}
ll mid = (l+r)/2;
ll res = inf;
if(a <= mid)
res = min( res,querymi(now*2,l,mid,a,b) );
if(b >= mid+1)
res = min( res,querymi(now*2+1,mid+1,r,a,b) );
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n;
for(ll i = 1; i <= n; i++)
{
cin >> a[i];
}
for(ll i = 1; i <= n; i++)
{
cin >> b[i];
preb[i] = preb[i-1] + b[i];
}
build(1,1,n);
a[0] = -inf;
stack<ll>S;
S.push(0);
for(ll i = 1; i <= n; i++)
{
while(a[S.top()] >= a[i])
{
S.pop();
}
arra[i].l = S.top();
S.push(i);
}
stack<ll>SS;
a[n+1] = -inf;
SS.push(n+1);
for(ll i = n; i >= 1; i--)
{
while(a[SS.top()] >= a[i])
{
SS.pop();
}
arra[i].r = SS.top();
SS.push(i);
}
for(ll i = 1; i <= n; i++)
{
ll l = arra[i].l,r = arra[i].r,num = a[i];
if(a[i] > 0)
{
ll tr = queryma(1,1,n,i,r-1);
ll tl = querymi(1,1,n,l,i);
ans = max(ans,1ll*a[i]*(tr-tl));
}
else
{
ll tr = querymi(1,1,n,i,r-1);
ll tl = queryma(1,1,n,l,i);
ans = max(ans,1ll*a[i]*(tr-tl));
}
}
cout << ans << endl;
return 0;
}
算法竞赛题解析

本文解析了一道算法竞赛题目,涉及序列处理、数据结构(单调栈、线段树)及复杂度优化,通过实例展示了如何求解序列中特定条件下的最大乘积问题。
827

被折叠的 条评论
为什么被折叠?



