Topic links: https://ac.nowcoder.com/acm/contest/884/C
Solution: enumeration of a sequence of each point to the current point as the minimum value, monotonically stack to find the current point to the first point is smaller than its left side can be achieved, to identify the current point on the right can be achieved a small point than it is, then the establishment of a prefix and the segment tree. Finally, traversing a of n points, when a [i] is less than 0, equal to find a prefix and a minimum value minus its left feasible range to find a prefix and the maximum value feasible interval to its right, as a [i] it is greater than 0, equal to the right to find a feasible interval prefix and its minimum value possible reduction in its left section prefix and find the maximum value, compare this value of n, taking the maximum that is the answer.
AC Code:
Language: C ++ code size: 2681 Run Time: 2123 ms take up memory: 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('\n') 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 }