牛客4 C sequence

  

用单调栈维护所管辖的区间左端和右端   并用线段树维护前缀和

//#pragma comment(linker, "/STACK:102400000,102400000")
#include "bits/stdc++.h"
#define pb push_back
#define ls l,m,now<<1
#define rs m+1,r,now<<1|1
#define hhh printf("hhh
")
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}
 
const int N=3e6+10;
struct node
{
    int l,r;
    ll maxx,minn;
}tree[N<<2];
ll sum[N],a[N];
ll b[N];
int n;
int l[N],r[N];
void pushup(int cur)
{
    tree[cur].maxx=max(tree[cur<<1].maxx,tree[cur<<1|1].maxx);
    tree[cur].minn=min(tree[cur<<1].minn,tree[cur<<1|1].minn);
}
void build(int l,int r,int cur)
{
    tree[cur].l=l;
    tree[cur].r=r;
    if(l==r)
    {
        tree[cur].maxx=tree[cur].minn=sum[l];
        return;
    }
    int mid=(r+l)>>1;
    build(l,mid,cur<<1);
    build(mid+1,r,cur<<1|1);
    pushup(cur);
 //   cout<<l<<" "<<r<<" "<<tree[cur].l<<" "<<tree[cur].maxx<<" "<<tree[cur].minn<<endl;
}
ll querymax(int pl,int pr,int cur)
{
    if(pl<=tree[cur].l&&tree[cur].r<=pr)
    {
        return tree[cur].maxx;
    }
    ll res=-1e18;
    if(pl<=tree[cur<<1].r) res=max(res,querymax(pl,pr,cur<<1));
    if(pr>=tree[cur<<1|1].l) res=max(res,querymax(pl,pr,cur<<1|1));
    return res;
}
ll querymin(int pl,int pr,int cur)
{
    if(pl<=tree[cur].l&&tree[cur].r<=pr)
    {
        return tree[cur].minn;
    }
    ll res=1e18;
    if(pl<=tree[cur<<1].r) res=min(res,querymin(pl,pr,cur<<1));
    if(pr>=tree[cur<<1|1].l) res=min(res,querymin(pl,pr,cur<<1|1));
  
    return res;
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i)
    {
        scanf("%lld", &b[i]);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    stack<int> s;
    for(int i=1;i<=n;i++)
    {
        while(!s.empty() && b[s.top()] >= b[i]) s.pop();
 
        if(s.empty()) l[i]=0;
        else
        {
            l[i]=s.top();
        }
 
        s.push(i);
    //     cout<<l[i]<<endl;
    }
    while(!s.empty()) s.pop();
    for(int i=n;i>=1;i--)
    {
        while(!s.empty() && b[s.top()] >= b[i]) s.pop();
        if(s.empty()) r[i]=n;
        else r[i]=s.top()-1;
        //   cout<<r[i]<<endl;
        s.push(i);
    }
 
    build(0,n,1);
    ll ans=-1e18,cnt;
    for(int i=1;i<=n;i++)
    {
        cnt=b[i];
        //   cout<<l[i]<<" "<<i-1<<" "<<i<<" "<<r[i]<<endl;
        if(cnt>0) cnt=cnt*(querymax(i,r[i],1)-querymin(l[i],i-1,1));
        else cnt=cnt*(querymin(i,r[i],1)-querymax(l[i],i-1,1));
    //    cout<<cnt<<endl;
        ans=max(ans,cnt);
    }
    printf("%lld
",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/11258692.html