loj10143. 「一本通 4.6 例 1」营业额统计
Posted junk-yao-blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了loj10143. 「一本通 4.6 例 1」营业额统计相关的知识,希望对你有一定的参考价值。
思路:
使用treap在线存数据,每次取出新读入数据的前驱与后继,与该数据差值较小的就是。(注意若已有同一个数据,特判ans+=0)
#include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> using namespace std; const int maxn = 100010; inline void qread(int &x) { x = 0; register int ch = getchar(), flag = 0; while(ch < ‘0‘ || ch > ‘9‘) { if(ch == ‘-‘) flag = 1; ch = getchar(); } while(ch >= ‘0‘ && ch <= ‘9‘) x = 10 * x + ch - 48, ch = getchar(); if(flag) x = -x; } int rt = 0, tpn, v[maxn], l[maxn], r[maxn], R[maxn], sz[maxn], vn[maxn]; inline void update(int x) { sz[x] = sz[l[x]] + sz[r[x]] + vn[x]; } inline void zig(int &x) { int t = l[x]; l[x] = r[t]; r[t] = x; update(x); update(t); x = t; } inline void zag(int &x) { int t = r[x]; r[x] = l[t]; l[t] = x; update(x); update(t); x = t; } void insert(int &x, int w) { if(!x) { x = ++tpn; v[x] = w; R[x] = rand(); sz[x] = vn[x] = 1; return ; } if(w < v[x]) insert(l[x], w); else if(w > v[x]) insert(r[x], w); else vn[x]++; update(x); if(l[x] && R[l[x]] < R[x]) zig(x); if(r[x] && R[r[x]] < R[x]) zag(x); } void pop(int &x, int w) { if(w < v[x]) pop(l[x], w); else if(w > v[x]) pop(r[x], w); else { if(vn[x] > 1) vn[x]--; else if(!l[x] || !r[x]) x = l[x] | r[x]; else if(R[l[x]] < R[r[x]]) zig(x), pop(x, w); else zag(x), pop(x, w); } update(x); } int ask(int x, int w){ if(!x) return -1; if(w < v[x]) return ask(l[x], w); if(w > v[x]) return ask(r[x], w); return x; } int findk(int x, int k){ if(k >= sz[l[x]] + 1 && k <= sz[l[x]] + vn[x]) return v[x]; if(k <= sz[l[x]]) return findk(l[x], k); return findk(r[x], k - sz[x] - vn[x]); } int findpre(int x, int w){ int res = -0x3f3f3f3f; while(x){ if(w <= v[x]) x = l[x]; else res = v[x], x = r[x]; } return res; } int findnxt(int x, int w){ int res = 0x3f3f3f3f; while(x){ if(w < v[x]) res = v[x], x = l[x]; else x = r[x]; } return res; } int main(void) { srand(11535); int n, ans; qread(n); qread(ans); insert(rt, ans); for(int i=2; i<=n; ++i){ int x; qread(x); int l = findpre(rt, x), r = findnxt(rt, x); if(ask(rt, x) != -1) {insert(rt, x); continue;} insert(rt, x); ans += min(x - l, r - x); } printf("%d ", ans); }
以上是关于loj10143. 「一本通 4.6 例 1」营业额统计的主要内容,如果未能解决你的问题,请参考以下文章
loj10145. 「一本通 4.6 练习 2」郁闷的出纳员