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

来源:互联网 发布:阿里云服务器推荐配置 编辑:程序博客网 时间:2024/04/29 13:52

【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 1000000int 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;}
1 0
原创粉丝点击