【平衡树】宠物收养所 HNOI 2004

【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;
}
posted @ 2019-12-14 14:52  _Ark  阅读(139)  评论(0编辑  收藏  举报