同一时间呆在收养所中的,要么全是宠物,要么全是领养者
做一个标记,标记现在收养所里的是人还是宠物
每次进来一个,判断他是同类还是异类
同类则ins
否则找先看有没有等期望值的
不然找期望值的前驱后继
判断哪个更接近,ans+=;删点;
都做不了,那么树就是空的,重新种树啦
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int len,root,bj=-1;//标记:0为宠物,1为人,-1为初始
struct node
{
int n,c,f,d,son[2];
} tr[10010];
void update(int x)
{
int lc=tr[x].son[0],rc=tr[x].son[1];
tr[x].c=tr[x].n+tr[lc].c+tr[rc].c;
}
void add(int d,int f)
{
len++;
tr[len].d=d;tr[len].f=f;tr[len].c=1;tr[len].n=1;
tr[len].son[1]=tr[len].son[0]=0;
if (d<tr[f].d) tr[f].son[0]=len; else tr[f].son[1]=len;
}
int findip(int d)
{
int x=root;
while (tr[x].d!=d)
{
if (d<tr[x].d)
{
if (tr[x].son[0]==0) break;
else x=tr[x].son[0];
}
else
{
if (tr[x].son[1]==0) break;
else x=tr[x].son[1];
}
}
return x;
}
void rotate(int x,int w)
{
int f=tr[x].f,ff=tr[f].f;
int r,R;
r=tr[x].son[w];R=f;
tr[R].son[1-w]=r;
if (r!=0) tr[r].f=R;
r=x;R=ff;
tr[r].f=R;
if (f==tr[ff].son[0]) tr[R].son[0]=r;
else tr[R].son[1]=r;
r=f;R=x;
tr[r].f=R;
tr[R].son[w]=r;
update(f);
update(x);
}
void splay(int x,int rt)
{
while (tr[x].f!=rt)
{
int f=tr[x].f,ff=tr[f].f;
if (rt==ff)
{
if (tr[f].son[0]==x) rotate(x,1);
else rotate(x,0);
}
else
{
if (tr[f].son[0]==x&&tr[ff].son[0]==f) {rotate(f,1);rotate(x,1);}
else if (tr[f].son[1]==x&&tr[ff].son[1]==f) {rotate(f,0);rotate(x,0);}
else if (tr[f].son[0]==x&&tr[ff].son[1]==f) {rotate(x,1);rotate(x,0);}
else if (tr[f].son[1]==x&&tr[ff].son[0]==f) {rotate(x,0);rotate(x,1);}
}
}
if (rt==0) root=x;
}
void ins(int d)
{
if (root==0)
{
add(d,len);
root=len;
return ;
}
else
{
int x=findip(d);
if (d==tr[x].d)
{
tr[x].n++;
update(x);
splay(x,0);
}
else
{
add(d,x);
update(x);
splay(len,0);
}
}
}
void del(int d)
{
int x=findip(d);
splay(x,0);
if (tr[x].d!=d) return ;
if (tr[x].n>1) {tr[x].n--;update(x);return ;}
if (tr[x].son[0]==0&&tr[x].son[1]==0) {root=0;len=0;tr[root].son[0]=tr[root].son[1]=0;}
else if (tr[x].son[0]==0&&tr[x].son[1]!=0) {root=tr[x].son[1];tr[root].f=0;}
else if (tr[x].son[0]!=0&&tr[x].son[1]==0) {root=tr[x].son[0];tr[root].f=0;}
else
{
int p=tr[x].son[0];
while (tr[p].son[1]!=0) p=tr[p].son[1];
splay(p,x);
int R=p,r=tr[x].son[1];
tr[R].son[1]=r;
tr[r].f=R;
tr[R].f=0;
root=R;
update(R);
}
}
int findqianqu(int d)
{
int x=findip(d);splay(x,0);
if (tr[x].d>=d&&tr[x].son[0]!=0)
{
x=tr[x].son[0];
while (tr[x].son[1]!=0) x=tr[x].son[1];
}
if (tr[x].d>=d) x=0;
return x;
}
int findhouji(int d)
{
int x=findip(d);splay(x,0);
if (tr[x].d<=d&&tr[x].son[1]!=0)
{
x=tr[x].son[1];
while (tr[x].son[0]!=0) x=tr[x].son[0];
}
if (tr[x].d<=d) x=0;
return x;
}
int findpaiming(int d)
{
int x=findip(d);splay(x,0);
return tr[tr[x].son[0]].c+1;
}
int findnum(int k)
{
int x=root;
while (1)
{
int lc=tr[x].son[0],rc=tr[x].son[1];
if (k<=tr[lc].c) x=lc;
else if (k>tr[lc].c+tr[x].n)
{
k-=tr[lc].c+tr[x].n;
x=rc;
}
else break;
}
splay(x,0);
return tr[x].d;
}
int main()
{
int a,b,c,d,cc,dd,n;
long long ans=0;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
if (bj==-1)
{
ins(b); bj=a; continue;
}
if (a==bj)
{
ins(b);
}
else
{
int x=findip(b);
splay(x,0);
if (tr[x].d==b) {del(b);}
else
{
c=findqianqu(b);
d=findhouji(b);
cc=tr[c].d;dd=tr[d].d;
if (c!=0&&d!=0)
{
if (abs(cc-b)==abs(dd-b))
{
ans+=abs(cc-b);
if (cc<dd) del(cc); else del(dd);
}
else
{
if (abs(cc-b)>abs(dd-b))
{
ans+=abs(dd-b);
del(dd);
}
else
{
ans+=abs(cc-b);
del(cc);
}
}
}
else if (c!=0&&d==0) {ans+=abs(b-cc);del(cc);}
else if (d!=0&&c==0) {ans+=abs(b-dd);del(dd);}
else {ins(b);bj=a;}
ans=ans%1000000;
}
}
}
printf("%d\n",ans%1000000);
return 0;
}