题目链接:https://ac.nowcoder.com/acm/contest/884/C
题解:枚举a序列中每个点,以当前的点作为最小值,用单调栈找出当前点到左边能达到的第一个比它小的点,找出当前点到右边能达到的第一个比它小的点,然后建立前缀和的线段树。最后,遍历a中n个点,当a[i]小于0时,等于 在它右边的可行区间找前缀和最小的值 减 在它左边的可行区间找前缀和最大的值,当a[i]大于0时,等于 在它右边的可行区间找前缀和最小的值 减 在它左边的可行区间找前缀和最大的值,比较这n个值,取最大即为答案。
AC代码:
语言:C++ 代码长度:2681 运行时间: 2123 ms 占用内存:267912K
1 #include<vector> 2 #include<cstdio> 3 #include<iostream> 4 #include<cmath> 5 #include<queue> 6 #include<stack> 7 #define numm ch-48 8 #define pd putchar(' ') 9 #define pn putchar(' ') 10 #define pb push_back 11 #define fi first 12 #define se second 13 #define fre1 freopen("1.txt","r",stdin) 14 #define fre2 freopen("2.txt","w",stdout) 15 using namespace std; 16 template <typename T> 17 void read(T &res) { 18 bool flag=false;char ch; 19 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 20 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 21 flag&&(res=-res); 22 } 23 template <typename T> 24 void write(T x) { 25 if(x<0) putchar('-'),x=-x; 26 if(x>9) write(x/10); 27 putchar(x%10+'0'); 28 } 29 const int maxn=3000010; 30 const int N=1010; 31 const int inf=0x3f3f3f3f; 32 typedef long long ll; 33 struct node { 34 int l,r; 35 ll minn,maxx; 36 }tree[maxn<<2]; 37 ll sum[maxn]; 38 int a[maxn],b[maxn]; 39 int l[maxn],r[maxn]; 40 int n; 41 void pushup(int cur) { 42 tree[cur].minn=min(tree[cur<<1].minn,tree[cur<<1|1].minn); 43 tree[cur].maxx=max(tree[cur<<1].maxx,tree[cur<<1|1].maxx); 44 } 45 void build(int l,int r,int cur) { 46 tree[cur].l=l; 47 tree[cur].r=r; 48 if(l==r) { 49 tree[cur].minn=tree[cur].maxx=sum[l]; 50 return ; 51 } 52 int mid=(l+r)>>1; 53 build(l,mid,cur<<1); 54 build(mid+1,r,cur<<1|1); 55 pushup(cur); 56 } 57 ll querymax(int ql,int qr,int cur) { 58 if(ql<=tree[cur].l&&tree[cur].r<=qr) 59 return tree[cur].maxx; 60 ll res=-1e18; 61 if(ql<=tree[cur<<1].r) res=max(querymax(ql,qr,cur<<1),res); 62 if(qr>=tree[cur<<1|1].l) res=max(querymax(ql,qr,cur<<1|1),res); 63 return res; 64 } 65 ll querymin(int ql,int qr,int cur) { 66 if(ql<=tree[cur].l&&tree[cur].r<=qr) 67 return tree[cur].minn; 68 ll res=1e18; 69 if(ql<=tree[cur<<1].r) res=min(querymin(ql,qr,cur<<1),res); 70 if(qr>=tree[cur<<1|1].l) res=min(querymin(ql,qr,cur<<1|1),res); 71 return res; 72 } 73 stack<int> s; 74 int main() 75 { 76 read(n); 77 for(int i=1;i<=n;i++) 78 read(a[i]); 79 for(int i=1;i<=n;i++) { 80 read(b[i]); 81 sum[i]=sum[i-1]+(ll)b[i]; 82 } 83 build(0,n,1); 84 for(int i=1;i<=n;i++) { 85 while(!s.empty()&&a[s.top()]>=a[i]) s.pop(); 86 if(s.empty()) l[i]=0; 87 else l[i]=s.top(); 88 s.push(i); 89 } 90 while(!s.empty()) s.pop(); 91 for(int i=n;i>=1;i--) { 92 while(!s.empty()&&a[s.top()]>=a[i]) s.pop(); 93 if(s.empty()) r[i]=n; 94 else r[i]=s.top()-1; 95 s.push(i); 96 } 97 ll res=-1e18; 98 for(int i=1;i<=n;i++) { 99 int x=a[i]; 100 if(x>0) 101 res=max((querymax(i,r[i],1)-querymin(l[i],i-1,1))*(ll)x,res); 102 else if(x<0) 103 res=max((querymin(i,r[i],1)-querymax(l[i],i-1,1))*(ll)x,res); 104 } 105 write(res);pn; 106 return 0; 107 }