单调栈
单调栈+线段树
细节
#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<<'\n'; 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<<'\n'; } cout<<ans<<'\n'; }
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<<'\n'; 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<<'\n'; } cout<<ans<<'\n'; }