当前位置:   article > 正文

线段树+单调栈+前缀和--2019icpc南昌网络赛I

在前缀和上的线段树

线段树+单调栈+前缀和--2019icpc南昌网络赛I

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 \times 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≤*a**i*≤105).

Output

One line contains an integer represent the answer of the array.

样例输入复制
  1. 5
  2. 1 2 3 4 5
样例输出复制
36

思路

前缀和,以每个a_i为最低点,用单调栈求出a_i的所能影响的范围

若a_i>=0,则maxR-minL

若a_i<0,则minR-min(0,maxL)

minR,和maxL用线段树查询,线段树构建:以前缀和为底,找出范围内的最值

代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <string>
  4. #include <cstring>
  5. #include <cmath>
  6. #include <sstream>
  7. #include <algorithm>
  8. #include <set>
  9. #include <map>
  10. #include <vector>
  11. #include <queue>
  12. #include <iomanip>
  13. #include <stack>
  14. using namespace std;
  15. typedef long long LL;
  16. const int INF = 0x3f3f3f3f;
  17. const int N = 5e5+5;
  18. const int MOD = 1e9 + 9;
  19. const double pi = 3.1415926;
  20. #define lson l, m, rt << 1
  21. #define rson m + 1, r, rt << 1 | 1
  22. #define F(i, l, r) for(int i = l;i <= (r);++i)
  23. #define RF(i, l, r) for(int i = l;i >= (r);--i)
  24. LL a[N], sum[N], tree_min[N << 2], tree_max[N << 2];
  25. void build(int l, int r, int rt)
  26. {
  27. if(l == r)
  28. {
  29. tree_min[rt] = tree_max[rt] = sum[l];
  30. return ;
  31. }
  32. int m = (l + r) >> 1;
  33. build(lson);
  34. build(rson);
  35. tree_max[rt] = max(tree_max[rt << 1], tree_max[rt << 1 | 1]);
  36. tree_min[rt] = min(tree_min[rt << 1], tree_min[rt << 1 | 1]);
  37. }
  38. LL Query_max(int L, int R, int l, int r, int rt)
  39. {
  40. if(L <= l && r <= R)
  41. return tree_max[rt];
  42. int m = (l + r) >> 1;
  43. LL ans = -1e18;
  44. if(L <= m)
  45. ans = max(ans, Query_max(L, R, lson));
  46. if(R > m)
  47. ans = max(ans, Query_max(L, R, rson));
  48. return ans;
  49. }
  50. LL Query_min(int L, int R, int l, int r, int rt)
  51. {
  52. if(L <= l && r <= R)
  53. return tree_min[rt];
  54. int m = (l + r) >> 1;
  55. LL ans = INF;
  56. if(L <= m)
  57. ans = min(ans, Query_min(L, R, lson));
  58. if(R > m)
  59. ans = min(ans, Query_min(L, R, rson));
  60. return ans;
  61. }
  62. stack<int> s;
  63. LL rig[N], lef[N];
  64. int main()
  65. {
  66. int n;
  67. cin >> n;
  68. F(i, 1, n)
  69. {
  70. cin >> a[i];
  71. sum[i] = sum[i - 1] + a[i];
  72. }
  73. build(1, n, 1);
  74. F(i, 1, n)
  75. {
  76. while(!s.empty() && a[s.top()] > a[i]) {rig[s.top()] = i - 1;s.pop();}
  77. s.push(i);
  78. }
  79. while(!s.empty())
  80. {
  81. rig[s.top()] = n;
  82. s.pop();
  83. }
  84. RF(i, n, 1)
  85. {
  86. while(!s.empty() && a[s.top()] > a[i]) {lef[s.top()] = i + 1;s.pop();}
  87. s.push(i);
  88. }
  89. while(!s.empty())
  90. {
  91. lef[s.top()] = 1;
  92. s.pop();
  93. }
  94. LL ans = -1e18, t;
  95. F(i, 1, n)
  96. {
  97. if(a[i] > 0)
  98. t = sum[rig[i]] - sum[lef[i] - 1];
  99. else
  100. t = Query_min(i, rig[i], 1, n, 1) - max(0ll, Query_max(lef[i], i, 1, n, 1));
  101. //cout << Query_min(i, rig[i], 1, n, 1) << " " << max(0ll, Query_max(lef[i], i, 1, n, 1)) << endl;
  102. ans = max(ans, t * a[i]);
  103. }
  104. cout << ans << endl;
  105. return 0;
  106. }

转载于:https://www.cnblogs.com/shuizhidao/p/10780756.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/654270
推荐阅读
相关标签
  

闽ICP备14008679号