Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values in the interval, multiplied by the smallest value in the interval.
Now she is planning to find the max value of the intervals in her array. Can you help her?
Input
First line contains an integer n(1 le n le 5 imes 10 ^5n(1≤n≤5×105).
Second line contains nn integers represent the array a (-10^5 le a_i le 10^5)a(−105≤ai≤105).
Output
One line contains an integer represent the answer of the array.
样例输入
5 1 2 3 4 5
样例输出
36
陈你
题意 : 给你 n 个元素,有正有负,要求你去寻找一个区间,要求区间中最小的元素乘以此元素所在的一段区间的和要最大,输出最大值
思路分析:
若元素全为正,显然就是单调栈的入门题了,但是现在元素有负的,因此需要换个角度去考虑
借助单调栈,我们可以找到每个元素作为最小值所在的区间
假设现在选取的一个元素是负的,那么我们是不就要找一段负的区间的和最小,乘起来才会使最大
那么这个时候就可以借助前缀和,该位置右边的最小值减去左边的最大值即可,若左边最大值小于0,此时就不要减去
用线段树去维护
一直有个地方写错,就是单调栈找每个元素所在区间的地方
代码示例:
#define ll long long const ll maxn = 5e5+5; const ll mod = 1e9+7; const double eps = 1e-9; const double pi = acos(-1.0); const ll inf = 0x3f3f3f3f; ll n; ll a[maxn]; ll lf[maxn], rf[maxn]; struct pp { ll num, id; }; struct pp sta[maxn]; struct node { ll l, r; ll mm, mi; }t[maxn<<2]; #define lson k<<1 #define rson k<<1|1 ll sum[maxn]; void init(){ ll top = 0; a[n+1] = -999999999; for(ll i = 1; i <= n+1; i++){ while(top > 0 && sta[top].num > a[i]){ rf[sta[top].id] = i-1; top--; } sta[++top] = {a[i], i}; } top = 0; for(ll i = 1; i <= n+1; i++){ ll pos = i; while(top > 0 && sta[top].num > a[i]){ pos = sta[top].id; top--; } sta[++top] = {a[i], pos}; lf[i] = pos; } } void build(ll l, ll r, ll k){ t[k].l = l, t[k].r = r; if (l == r){ t[k].mm = t[k].mi = sum[l]; return; } ll mid = (l+r)>>1; build(l, mid, lson); build(mid+1, r, rson); t[k].mm = max(t[lson].mm, t[rson].mm); t[k].mi = min(t[lson].mi, t[rson].mi); } ll qmax(ll l, ll r, ll k){ ll ans = -1e18; if (l <= t[k].l && t[k].r <= r) { return t[k].mm; } ll mid = (t[k].l+t[k].r)>>1; if (l <= mid) ans = max(ans, qmax(l, r, lson)); if (r > mid) ans = max(ans, qmax(l, r, rson)); return ans; } ll qmin(ll l, ll r, ll k){ ll ans = 1e18; if (l <= t[k].l && t[k].r <= r) { return t[k].mi; } ll mid = (t[k].l+t[k].r)>>1; if (l <= mid) ans = min(ans, qmin(l, r, lson)); if (r > mid) ans = min(ans, qmin(l, r, rson)); return ans; } void solve(){ for(ll i = 1; i <= n; i++){ sum[i] = sum[i-1]+a[i]; } ll ans = 0; build(1, n, 1); for(ll i = 1; i <= n; i++){ if (a[i]>0) ans = max(ans, (sum[rf[i]]-sum[lf[i]-1])*a[i]); else { ans = max(ans, a[i]*(qmin(i, rf[i], 1ll)-max(qmax(lf[i], i, 1ll), 0ll))); } } printf("%lld ", ans); } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); cin >> n; for(ll i = 1; i <= n; i++){ scanf("%lld", &a[i]); } init(); solve(); return 0; }