loj10144. 「一本通 4.6 练习 1」宠物收养所
Posted junk-yao-blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了loj10144. 「一本通 4.6 练习 1」宠物收养所相关的知识,希望对你有一定的参考价值。
思路:
treap+简单模拟。
我只能说:注意取模!!!!
#include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> using namespace std; const int maxn = 80010; 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 = 0, mode = 0; qread(n); for(int i=1; i<=n; ++i){ int x, a; qread(x), qread(a); if(!sz[rt]) { insert(rt, a); mode = x; continue; } if(x != mode){ if(ask(rt, a) == -1){ int l = findpre(rt, a), r = findnxt(rt, a); int minn = min(a - l, r - a), d; if(a + minn == r) d = r; if(a - minn == l) d = l; pop(rt, d); ans += minn; ans %= 1000000; } else pop(rt, a); } else insert(rt, a); } printf("%d ", ans%1000000); }
以上是关于loj10144. 「一本通 4.6 练习 1」宠物收养所的主要内容,如果未能解决你的问题,请参考以下文章
loj10195. 「一本通 6.1 练习 2」转圈游戏 (loj2608)