sequence

链接: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}a1n and b1…nb_{1 \dots n}b1n .You need to answer max⁡1≤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})\}1lrnmax{min(alr)×sum(blr)} 。

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}a1n .

The third line contains n integers meaning b1…nb_{1 \dots n}b1n .

输出描述:

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^61n3×106,106ai,bi106.
#include<iostream>
#include<cstdio>
#include<cstring>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e6+7;
ll mx[maxn<<2],mn[maxn<<2];
ll sum[maxn];
ll a[maxn],b[maxn];
int n;
int l[maxn],r[maxn];
void pushup(int rt){
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
    mn[rt]=min(mn[rt<<1],mn[rt<<1|1]);
}
void build(int rt,int l,int r){
    if(l==r){
        mx[rt]=mn[rt]=sum[l];
        return;
    }
    int mid=l+r>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
    pushup(rt);
}
ll query_min(int rt,int ql,int qr,int L,int R){
    if(L>=ql&&R<=qr){
        return mn[rt];
    }
    int mid=L+R>>1;
    ll cur=0x3f3f3f3f3f;
    if(ql<=mid){
        cur=min(cur,query_min(rt<<1,ql,qr,L,mid));
    }
    if(qr>mid){
        cur=min(cur,query_min(rt<<1|1,ql,qr,mid+1,R));
    }
    return cur;
}
ll query_max(int rt,int ql,int qr,int L,int R){
    if(L>=ql&&R<=qr){
        return mx[rt];
    }
    int mid=L+R>>1;
    ll cur=-0x3f3f3f3f;
    if(ql<=mid){
        cur=max(cur,query_max(rt<<1,ql,qr,L,mid));
    }
    if(qr>mid){
        cur=max(cur,query_max(rt<<1|1,ql,qr,mid+1,R));
    }
    return cur;
}
int main(){
    //freopen("1.txt","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%lld",a+i);
    }
    for(int i=1;i<=n;++i){
        scanf("%lld",b+i);
    }
    for(int i=1;i<=n;++i){
        sum[i]=sum[i-1]+b[i];
    }
    build(1,1,n);
    //sum[n+1]=sum[n];
    stack<int>sk;
    sk.push(1);
    l[1]=1;
    for(int i=2;i<=n;++i){
        while(!sk.empty()&&a[i]<=a[sk.top()]){
            sk.pop();
        }
        if(sk.empty()){
            l[i]=1;
        }
        else{
            l[i]=sk.top()+1;
        }
        sk.push(i);
    }
    while(!sk.empty())sk.pop();
    sk.push(n);
    r[n]=n;
    for(int i=n-1;i>=1;--i){
        while(!sk.empty()&&a[i]<=a[sk.top()]){
            sk.pop();
        }
        if(sk.empty()){
            r[i]=n;
        }
        else{
            r[i]=sk.top()-1;
            //cerr<<"debug:"<<i<<' '<<r[i]<<endl;
        }
        sk.push(i);
        //cerr<<sk.size()<<endl;
    }
    //cout<<"debug:"<<query_max(1,1,3,1,3)<<' '<<query_min(1,1,3,1,3)<<endl;
//    while(!sk.empty()){
//        r[sk.top()]=n;
//        sk.pop();
//    }
    //for(int i=1;i<=n;++i)cout<<l[i]<<' '<<r[i]<<endl;
    ll ans=-0x3f3f3f3f3f3f3fll;
    for(int i=1;i<=n;++i){
        ll cur=a[i];
        if(a[i]<0){
            //cout<<l[i]<<' '<<i<<' '<<r[i]<<' '<<query_min(1,i,r[i],1,n)<<' '<<query_max(1,l[i],i,1,n)<<endl;
            if(l[i]<i){
                cur=a[i]*(query_min(1,i,r[i],1,n)-query_max(1,l[i],i-1,1,n));
            }
            else{
                cur=a[i]*(query_min(1,i,r[i],1,n)-sum[i-1]);
            }
        }
        else{
            //cout<<l[i]<<' '<<i<<' '<<r[i]<<' '<<query_min(1,i,r[i],1,n)<<' '<<query_max(1,l[i],i,1,n)<<endl;
            if(l[i]<i){
                cur=a[i]*(query_max(1,i,r[i],1,n)-query_min(1,l[i],i-1,1,n));
            }
            else{
                cur=a[i]*(query_max(1,i,r[i],1,n)-sum[i-1]);
            }
        }
        //cerr<<i<<' '<<cur<<endl;
        ans=max(ans,cur);
    }
    printf("%lld\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/czy-power/p/11256646.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值