博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2019牛客暑期多校训练营(第四场)- sequence
阅读量:4951 次
发布时间:2019-06-11

本文共 3009 字,大约阅读时间需要 10 分钟。

单调栈 + 线段树

先单调栈预处理a中每一个数覆盖的范围,然后用线段树维护b的前缀和,在选i的范围内查询区间值。

讨论一下a的正负性

#include 
#define INF 0x3f3f3f3f#define full(a, b) memset(a, b, sizeof a)#define FAST_IO ios::sync_with_stdio(false)using namespace std;typedef long long LL;inline int lowbit(int x){ return x & (-x); }inline int read(){ int ret = 0, w = 0; char ch = 0; while(!isdigit(ch)){ w |= ch == '-', ch = getchar(); } while(isdigit(ch)){ ret = (ret << 3) + (ret << 1) + (ch ^ 48); ch = getchar(); } return w ? -ret : ret;}inline int lcm(int a, int b){ return a / __gcd(a, b) * b; }template
inline A fpow(A x, B p, C lyd){ A ans = 1; for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd; return ans;}const int N = 4000005;int n, a[N], b[N], L[N], R[N];LL mx[N<<2], mn[N<<2], sum[N];void calc(){ stack
st; a[0] = a[n + 1] = -INF; st.push(0); for(int i = 1; i <= n; i ++){ while(!st.empty() && a[st.top()] >= a[i]) st.pop(); L[i] = st.top(); st.push(i); } while(!st.empty()) st.pop(); st.push(n + 1); for(int i = n; i >= 1; i --){ while(!st.empty() && a[st.top()] >= a[i]) st.pop(); R[i] = st.top(); st.push(i); }}void push_up(int rt){ mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]); mn[rt] = min(mn[rt << 1], mn[rt << 1 | 1]);}void buildTree(int rt, int l, int r){ if(l == r){ mx[rt] = mn[rt] = sum[l]; return; } int mid = (l + r) >> 1; buildTree(rt << 1, l, mid); buildTree(rt << 1 | 1, mid + 1, r); push_up(rt);}LL queryMax(int rt, int l, int r, int ql, int qr){ if(l == ql && r == qr){ return mx[rt]; } int mid = (l + r) >> 1; if(qr <= mid) return queryMax(rt << 1, l, mid, ql, qr); else if(ql > mid) return queryMax(rt << 1 | 1, mid + 1, r, ql, qr); else return max(queryMax(rt << 1, l, mid, ql, mid), queryMax(rt << 1 | 1, mid + 1, r, mid + 1, qr));}LL queryMin(int rt, int l, int r, int ql, int qr){ if(l == ql && r == qr){ return mn[rt]; } int mid = (l + r) >> 1; if(qr <= mid) return queryMin(rt << 1, l, mid, ql, qr); else if(ql > mid) return queryMin(rt << 1 | 1, mid + 1, r, ql, qr); else return min(queryMin(rt << 1, l, mid, ql, mid), queryMin(rt << 1 | 1, mid + 1, r, mid + 1, qr));}int main(){ n = read(); for(int i = 1; i <= n; i ++) a[i] = read(); for(int i = 1; i <= n; i ++) b[i] = read(); for(int i = 1; i <= n; i ++) sum[i] = sum[i - 1] + b[i]; calc(); buildTree(1, 0, n); LL ans = 0; for(int i = 1; i <= n; i ++){ int pl = L[i], pr = i - 1; int sl = i, sr = R[i] - 1; if(a[i] < 0){ ans = max(ans, 1LL * a[i] * (queryMin(1, 0, n, sl, sr) - queryMax(1, 0, n, pl, pr))); } else if(a[i] > 0){ ans = max(ans, 1LL * a[i] * (queryMax(1, 0, n, sl, sr) - queryMin(1, 0, n, pl, pr))); } } printf("%lld\n", ans); return 0;}

转载于:https://www.cnblogs.com/onionQAQ/p/11260417.html

你可能感兴趣的文章
最短路径之Bellman-Ford(可以解决负边)
查看>>
wincc7.4安装授权 全(文件分享)
查看>>
作为JavaScript开发人员,这些必备的VS Code插件你都用过吗?
查看>>
省选爆零记
查看>>
1. 微博大学数学答疑系列(1)
查看>>
如何让windows版Safari支持H5 audio/video?
查看>>
Android开源项目源码下载(不断更新中)
查看>>
opendove中的odgw所需要的内核模块
查看>>
记录cmder安装和更换背景图
查看>>
PS完美破解安装
查看>>
const函数
查看>>
第一天开通博客园
查看>>
HDU1754(线段树)
查看>>
如何去掉HTML5Viewer中的滚动条
查看>>
并查集 分类: 并查集 2015-07-09 16:...
查看>>
Oracle数据文件迁移
查看>>
ORACLE基本操作
查看>>
KernelZ02_尝试过程
查看>>
NGUIJoysticK
查看>>
JavaScript之DOM转Jquery对象
查看>>