【HNOI2004】宠物收养所
题目描述链接

​http://www.lydsy.com/JudgeOnline/problem.php?id=1208​

重点:

  1. 任何两只宠物的特点值都不可能是相同的,任何两个领养者的希望领养宠物的特点值也不可能是一样的
  2. 如果有两只满足要求的宠物,即存在两只宠物他们的特点值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物。
  3. 如果有两个满足要求的领养者,即存在两个领养者希望特点值分别为a-b和a+b,那么特点值为a-b的那个领养者将领养该宠物。

avl代码

#include<cstdio>
#include<cstring>
#define INF 1000000000
#define MAXN 10010
#define MOD 1000000
int n,cnt,s,root;//cnt 结点数量 root 根节点 s 不满意程度之和
bool flag;//flag=0:全是动物;flag=1:全是人
int tmp;//表示收养所中人或宠物的数量
struct node
{
int ls,rs,data;
int h;
}tr[MAXN];

int max(int x,int y){return (x>y)?x:y;}
int min(int x,int y){return (x<y)?x:y;}
int abs(int x,int y){return max(x,y)-min(x,y);}

void update(int r)
{
tr[r].h=max(tr[tr[r].ls].h,tr[tr[r].rs].h)+1;
return;
}

int zig(int r)
{
int t=tr[r].ls;
tr[r].ls=tr[t].rs;
tr[t].rs=r;
update(r);
update(t);
return t;
}

int zag(int r)
{
int t=tr[r].rs;
tr[r].rs=tr[t].ls;
tr[t].ls=r;
update(r);
update(t);
return t;
}

int zigzag(int r)
{
tr[r].rs=zig(tr[r].rs);
return zag(r);
}

int zagzig(int r)
{
tr[r].ls=zag(tr[r].ls);
return zig(r);
}

void maintain(int &r)
{
if(tr[tr[r].ls].h==tr[tr[r].rs].h+2)
{
int t=tr[r].ls;
if(tr[tr[t].ls].h==tr[tr[r].rs].h+1) r=zig(r);
else if(tr[tr[t].rs].h==tr[tr[r].rs].h+1) r=zagzig(r);
}
else if(tr[tr[r].ls].h+2==tr[tr[r].rs].h)
{
int t=tr[r].rs;
if(tr[tr[t].rs].h==tr[tr[r].ls].h+1) r=zag(r);
else if(tr[tr[t].ls].h==tr[tr[r].ls].h+1) r=zigzag(r);
}
update(r);
}

void insert(int &r,int x)
{
if(r==0){tr[r=(++cnt)].data=x;return;}
insert(x<tr[r].data?tr[r].ls:tr[r].rs,x);
maintain(r);
return;
}

int minn(int a,int b,int c)
{
int a1=abs(a,c);
int a2=abs(b,c);
if(a1>a2) return b;
if(a1<a2) return a;
return a<b?a:b;
}

int find(int r,int x)
{
if(r==0) return INF;
if(tr[r].data==x) return tr[r].data;
if(tr[r].data<x) return minn(tr[r].data,find(tr[r].rs,x),x);
else return minn(tr[r].data,find(tr[r].ls,x),x);
}

int Delete(int &r,int x)
{int tx;
if(x==tr[r].data||(x<tr[r].data&&tr[r].ls==0)||(x>tr[r].data&&tr[r].rs==0))
{
if(tr[r].ls==0||tr[r].rs==0)
{
tx=tr[r].data;
r=tr[r].ls+tr[r].rs;
return tx;
}
else tr[r].data=Delete(tr[r].ls,x);
}
else
{
if(x<tr[r].data)
tx=Delete(tr[r].ls,x);
else tx=Delete(tr[r].rs,x);
}
maintain(r);
return tx;
}


int main()
{int x,y;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
if(!tmp)
{
flag=x;if(!x)tmp++;else tmp--;
memset(tr,0,sizeof tr);
root=0;cnt=0;insert(root,y);
}
else
{
if(x==flag)
{
if(!flag)tmp++;else tmp--;
insert(root,y);
}
else
{
if(!flag)tmp--;else tmp++;
int d=find(root,y);
s=(s+abs(d,y))%MOD;
Delete(root,d);
}
}
}
printf("%d\n",s);
return 0;
}