Bzoj1208--Hnoi2004宠物收养所
Treap太生硬了,还是Splay妖艳。
肆意乱扭
代码。。:
#include<bits/stdc++.h> #define MAXN 80005 #define MAXM 3005 #define INF 1000000000 #define MOD 1000000 #define LL long long using namespace std; int n,cnt,ans; struct Node{ int son[2],par,v; }x[MAXN]; struct Splay{ int L,R,root; void init() {L=0,R=1;cnt=0;root=0;} inline void PreSuf(int num,int &le,int &ri) { le=x[root].son[L],ri=x[root].son[R]; while(x[le].son[R]) le=x[le].son[R];while(x[ri].son[L]) ri=x[ri].son[L]; } inline void rotate(int num,int p) { int pa=x[num].par; if(x[pa].par) x[x[pa].par].son[x[x[pa].par].son[L]==pa?L:R]=num; x[pa].son[p^1]=x[num].son[p];if(x[num].son[p]) {x[x[num].son[p]].par=pa;} x[num].son[p]=pa;x[num].par=x[pa].par;x[pa].par=num; } inline void Splay_N(int num,int gl=0) { int pre,ppre; while(x[num].par!=gl) { if(x[x[num].par].par==gl) rotate(num,x[x[num].par].son[L]==num?R:L); else { pre=x[x[num].par].son[L]==num?R:L;ppre=x[x[x[num].par].par].son[L]==x[num].par?R:L; if(pre==ppre) rotate(x[num].par,ppre),rotate(num,pre); else rotate(num,pre),rotate(num,ppre); } } if(!gl) root=num; } void Insert(int v) { if(!root) {root=++cnt;x[cnt].v=v;return;} int now=root,pre; while(true) { pre=v>x[now].v?R:L; if(!x[now].son[pre]) {x[now].son[pre]=++cnt;x[cnt].v=v;x[cnt].par=now;break;} now=x[now].son[pre]; } Splay_N(cnt); } int Find(int v) { int now=root,pre; while(true) { if(x[now].v==v) { Splay_N(now); return now; } pre=v>x[now].v?R:L; if(!x[now].son[pre]) return 0; now=x[now].son[pre]; } } void Del(int v) { int now=Find(v),le,ri;if(!now) return; if(!x[now].son[L]) {root=x[now].son[R],x[root].par=0;return;} if(!x[now].son[R]) {root=x[now].son[L],x[root].par=0;return;} PreSuf(now,le,ri); Splay_N(le);Splay_N(ri,root); x[x[root].son[R]].son[L]=0; } int Qurey(int v) { if(!root) return -1; int now=Find(v); if(!now) Insert(v);else {Del(v);return 0;} now=Find(v);int le,ri; PreSuf(now,le,ri); if(!le) now=x[ri].v; else if(!ri) now=x[le].v; else now=v-x[le].v>x[ri].v-v?x[ri].v:x[le].v; Del(now);Del(v); return abs(v-now); } }; int main() { scanf("%d",&n); Splay p[2];p[0].init();p[1].init(); for(int a,b,t,i=1;i<=n;i++) { scanf("%d%d",&a,&b); t=p[a^1].Qurey(b); if(t==-1) p[a].Insert(b); else ans+=t,ans%=MOD; } printf("%d\n",ans); return 0; }