【题目链接】
https://www.lydsy.com/JudgeOnline/problem.php?id=1208
【算法】
建两棵平衡树维护领养者和宠物的特点值,这两棵平衡树支持 插入删除,查询前驱和后继
笔者的平衡树选用的是Treap,当然,Splay,Set等数据结构也是可以完成这个任务的
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 80010 typedef long long ll; const ll INF = 1e15; const int P = 1000000; int i,n,ans,a; ll p,q,b; struct Treap { int root,total; struct Node { int l,r; int priority; ll val; } a[MAXN]; inline void new_node(int pos,ll x) { a[pos].priority = rand(); a[pos].val = x; } inline void zig(int &p) { int q = a[p].l; a[p].l = a[q].r; a[q].r = p; p = q; } inline void zag(int &p) { int q = a[p].r; a[p].r = a[q].l; a[q].l = p; p = q; } inline void insert(int &x,ll val) { int now; if (!root) { new_node(++total,val); root = total; return; } if (val < a[x].val) { if (a[x].l) { insert(a[x].l,val); if (a[a[x].l].priority > a[x].priority) zig(x); } else { new_node(++total,val); a[x].l = total; } } else { if (a[x].r) { insert(a[x].r,val); if (a[a[x].r].priority > a[x].priority) zag(x); } else { new_node(++total,val); a[x].r = total; } } } inline void erase(int &x,ll val) { if (x == 0) return; if (a[x].val == val) { if (a[x].l || a[x].r) { if (a[x].r == 0 || a[a[x].l].priority > a[a[x].r].priority) { zig(x); erase(a[x].r,val); } else { zag(x); erase(a[x].l,val); } } else x = 0; } else { if (val < a[x].val) erase(a[x].l,val); else erase(a[x].r,val); } } inline ll pred(int x,ll val) { ll t; if (!x) return -INF; if (a[x].val == val) return val; if (val > a[x].val) { t = pred(a[x].r,val); return (t == -INF) ? a[x].val : t; } else return pred(a[x].l,val); } inline ll succ(int x,ll val) { ll t; if (!x) return INF; if (a[x].val == val) return val; if (val < a[x].val) { t = succ(a[x].l,val); return (t == INF) ? a[x].val : t; } else return succ(a[x].r,val); } } T1,T2; int main() { srand(123456); scanf("%d",&n); for (i = 1; i <= n; i++) { scanf("%d%lld",&a,&b); if (a == 0) { if (T2.root) { p = T2.pred(T2.root,b); q = T2.succ(T2.root,b); if (p == -INF && q == INF) continue; if (b - p <= q - b) { T2.erase(T2.root,p); ans = (ans + b - p) % P; } else { T2.erase(T2.root,q); ans = (ans + q - b) % P; } } else T1.insert(T1.root,b); } else { if (T1.root) { p = T1.pred(T1.root,b); q = T1.succ(T1.root,b); if (p == -INF && q == INF) continue; if (b - p <= q - b) { T1.erase(T1.root,p); ans = (ans + b - p) % P; } else { T1.erase(T1.root,q); ans = (ans + q - b) % P; } } else T2.insert(T2.root,b); } } printf("%d ",ans); return 0; }