单调栈

Max answer

单调栈+线段树

细节

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define maxn 500005
#define P pair<int,int>
P I[maxn];
stack<int> st;
int A[maxn];
//int B[maxn];
struct Nod
{
    LL mi,ma;
} N[maxn*3];
LL sum[maxn];
int n;
void upd(int x)
{

    N[x].mi=min(N[x<<1].mi,N[x<<1|1].mi);
    N[x].ma=max(N[x<<1].ma,N[x<<1|1].ma);

}
void build(int x,int l,int r)
{

    if(l==r)
    {
        N[x].ma=N[x].mi=sum[l];
        return;
    }
    int mid=l+r>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    upd(x);
}
void getMin()
{
    for(int i=1; i<=n; i++)
    {
        if(st.empty())
        {
            I[i].first=0;
            st.push(i);
        }
        else
        {
            if(A[st.top()]<A[i])
            {
                //cout<<i<<endl;
                I[i].first=st.top();
                st.push(i);
            }
            else
            {
                while(!st.empty()&&A[st.top()]>=A[i])
                {

                    st.pop();

                }
                if(st.empty())I[i].first=0;
                else
                    I[i].first=st.top();
                st.push(i);
            }
        }
    }
    while(!st.empty())st.pop();
    for(int i=n; i>=1; i--)
    {
        if(st.empty())
        {
            I[i].second=n+1;
            st.push(i);
        }
        else
        {
            if(A[st.top()]<A[i])
            {
                I[i].second=st.top();
                st.push(i);
            }
            else
            {
                while(!st.empty()&&A[st.top()]>=A[i])
                {

                    st.pop();

                }
                if(st.empty())I[i].second=n+1;
                else I[i].second=st.top();
                st.push(i);
            }
        }
    }
}
LL query(int l,int r,int f,int ll,int  rr,int x)///查询区间 ll rr
{
    //cout<<ll<<rr<<endl;
    //cout<<l<<r<<endl;
    //if(ll>rr)return A[rr];
   // cout<<l<<r<<ll<<rr<<endl;
    if(ll<=l&&r<=rr)
    {
        if(f)
        {
            //cout<<N[x].mi<<"QIIIIQ"<<x<<endl;
            return N[x].mi;
        }
        else
            return N[x].ma;
    }
    int mid= l+r>>1;
  //  cout<<mid<<'
';
    LL a,b;
    bool ff=0,gg=0;
    if(ll<=mid)a=query(l,mid,f,ll,rr,x<<1),ff=1;
    if(mid<rr)b=query(mid+1,r,f,ll,rr,x<<1|1),gg=1;
    if(ff&&gg&&f)
    {
        return min(a,b);
    }
    else if(ff&&gg)
    {
        return max(a,b);
    }
    else if(ff)
    {
        return a;
    }
    else return b;

}
int main()
{

    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&A[i]);
    }
    //int tt;
    for(int i=1; i<=n; i++)
    {
       // scanf("%d",&tt);
        sum[i]=sum[i-1]+A[i];
    }
    build(1,0,n);
    getMin();
    
    LL ans=0;
    for(int i=1; i<=n; i++)
    {
        if(A[i]==0)
        {
            ans=max(ans,0LL);
        }
        else if(A[i]>0)
        {
            LL x=query(0,n,1,I[i].first,i-1,1);
            
            LL y=query(0,n,0,i,I[i].second-1,1);
            //cout<<i<<' '<<I[i].first<<' '<<x<<"x"<<y<<endl;
            ans=max(ans,A[i]*(y-x));
        }
        else
        {
            LL x=query(0,n,0,I[i].first,i-1,1);
            LL y=query(0,n,1,i,I[i].second-1,1);
            ans=max(ans,A[i]*(y-x));
        }
       // cout<<ans<<'
';
    }
    cout<<ans<<'
';
}

 sequence 线段树查询写炸了一直内存超限。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define maxn 3000005
#define P pair<int,int>
P I[maxn];
stack<int> st;
int A[maxn];
//int B[maxn];
//#define INF 10000000008
struct Nod
{
    LL mi,ma;
} N[maxn*3];
LL sum[maxn];
int n;
void upd(int x)
{

    N[x].mi=min(N[x<<1].mi,N[x<<1|1].mi);
    N[x].ma=max(N[x<<1].ma,N[x<<1|1].ma);

}
void build(int x,int l,int r)
{

    if(l==r)
    {
        N[x].ma=N[x].mi=sum[l];
        return;
    }
    int mid=l+r>>1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    upd(x);
}
void getMin()
{
    for(int i=1; i<=n; i++)
    {
        if(st.empty())
        {
            I[i].first=0;
            st.push(i);
        }
        else
        {
            if(A[st.top()]<A[i])
            {
                //cout<<i<<endl;
                I[i].first=st.top();
                st.push(i);
            }
            else
            {
                while(!st.empty()&&A[st.top()]>=A[i])
                {

                    st.pop();

                }
                if(st.empty())I[i].first=0;
                else
                    I[i].first=st.top();
                st.push(i);
            }
        }
    }
    while(!st.empty())st.pop();
    for(int i=n; i>=1; i--)
    {
        if(st.empty())
        {
            I[i].second=n+1;
            st.push(i);
        }
        else
        {
            if(A[st.top()]<A[i])
            {
                I[i].second=st.top();
                st.push(i);
            }
            else
            {
                while(!st.empty()&&A[st.top()]>=A[i])
                {

                    st.pop();

                }
                if(st.empty())I[i].second=n+1;
                else I[i].second=st.top();
                st.push(i);
            }
        }
    }
}
LL query(int l,int r,int f,int ll,int  rr,int x)///查询区间 ll rr
{
    //cout<<ll<<rr<<endl;
    //cout<<l<<r<<endl;
    //if(ll>rr)return A[rr];
   // cout<<l<<r<<ll<<rr<<endl;
    if(ll<=l&&r<=rr)
    {
        if(f)
        {
            //cout<<N[x].mi<<"QIIIIQ"<<x<<endl;
            return N[x].mi;
        }
        else
            return N[x].ma;
    }
    int mid= l+r>>1;
  //  cout<<mid<<'
';
    LL a,b;
    bool ff=0,gg=0;
    if(ll<=mid)a=query(l,mid,f,ll,rr,x<<1),ff=1;
    if(mid<rr)b=query(mid+1,r,f,ll,rr,x<<1|1),gg=1;
    if(ff&&gg&&f)
    {
        return min(a,b);
    }
    else if(ff&&gg)
    {
        return max(a,b);
    }
    else if(ff)
    {
        return a;
    }
    else return b;

}
int main()
{

    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&A[i]);
    }
    int tt;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&tt);
        sum[i]=sum[i-1]+tt;
    }
    build(1,0,n);
    getMin();
    
    LL ans=0;
    for(int i=1; i<=n; i++)
    {
        if(A[i]==0)
        {
            ans=max(ans,0LL);
        }
        else if(A[i]>0)
        {
            LL x=query(0,n,1,I[i].first,i-1,1);
            
            LL y=query(0,n,0,i,I[i].second-1,1);
            //cout<<i<<' '<<I[i].first<<' '<<x<<"x"<<y<<endl;
            ans=max(ans,A[i]*(y-x));
        }
        else
        {
            LL x=query(0,n,0,I[i].first,i-1,1);
            LL y=query(0,n,1,i,I[i].second-1,1);
            ans=max(ans,A[i]*(y-x));
        }
       // cout<<ans<<'
';
    }
    cout<<ans<<'
';
}
原文地址:https://www.cnblogs.com/liulex/p/11271982.html