C++之路进阶——splay树(宠物收养所)

1285 宠物收养所

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题目描述 Description

最近,阿Q开了一间宠物收养所。收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物。 
每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值。这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少。 
1. 被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值为a,那么它将会领养一只目前未被领养的宠物中特点值最接近a的一只宠物。(任何两只宠物的特点值都不可能是相同的,任何两个领养者的希望领养宠物的特点值也不可能是一样的)如果有两只满足要求的宠物,即存在两只宠物他们的特点值分别为a-b和a+b那么领养者将会领养特点值为a-b的那只宠物。 
2. 收养宠物的人过多,假若到来一只被收养的宠物,那么哪个领养者能够领养它呢?能够领养它的领养者,,是那个希望被领养宠物的特点值最接近该宠物特点值的领养者,如果该宠物的特点值为a,存在两个领养者他们希望领养宠物的特点值分别为a-b和a+b,那么特点值为a-b的那个领养者将成功领养该宠物。

一个领养者领养了一个特点值为a的宠物,而它本身希望领养的宠物的特点值为b,那么这个领养者的不满意程度为abs(a-b)。

【任务描述】 
你得到了一年当中,领养者和被收养宠物到来收养所的情况,希望你计算所有收养了宠物的领养者的不满意程度的总和。这一年初始时,收养所里面既没有宠物,也没有领养者。

输入描述 Input Description

第一行为一个正整数n,n<=80000,表示一年当中来到收养所的宠物和领养者的总数。接下来的n行,按到来时间的先后顺序描述了一年当中来到收养所的宠物和领养者的情况。每行有两个正整数a, b,其中a=0表示宠物,a=1表示领养者,b表示宠物的特点值或是领养者希望领养宠物的特点值。(同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个)

输出描述 Output Description

仅有一个正整数,表示一年当中所有收养了宠物的领养者的不满意程度的总和mod 1000000以后的结果。

样例输入 Sample Input

5

0 2

0 4

1 3

1 2

1 5

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

(abs(3-2) + abs(2-4)=3,最后一个领养者没有宠物可以领养)

代码:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #define maxn 10100
  5
  6 using namespace std;
  7
  8 int n,tr[maxn][2],num[maxn],fa[maxn],kind,root,size,after,before,ans;
  9
 10 void rotate(int &k,int x)
 11    {
 12         int y=fa[x],z=fa[y],l,r;
 13         if (tr[y][0]==x) l=0; else l=1;
 14           r=l^1;
 15         if (k==y) k=x;
 16            else
 17           if (tr[z][0]==y) tr[z][0]=x; else tr[z][1]=x;
 18      fa[x]=z; fa[y]=x; fa[tr[x][r]]=y;
 19      tr[y][l]=tr[x][r]; tr[x][r]=y;
 20    }
 21
 22 void splay(int &k,int x)
 23     {
 24       int y,z;
 25       while (x!=k)
 26         {
 27           y=fa[x];
 28           z=fa[y];
 29           if (y!=k)
 30              {
 31                  if ((tr[z][0]==y)^(tr[y][0]==x)) rotate(k,x);
 32                      else rotate(k,y);
 33               }
 34             rotate(k,x);
 35          }
 36
 37     }
 38
 39 void ins(int &k,int x,int last)
 40     {
 41       if(k==0)
 42        {
 43            size++;
 44            k=size;
 45            num[k]=x;
 46            fa[k]=last;
 47            splay(root,k);
 48            return;
 49        }
 50      if (x<num[k]) ins(tr[k][0],x,k); else ins(tr[k][1],x,k);
 51     }
 52
 53 void del(int x)
 54     {
 55       splay(root,x);
 56         if (tr[x][0]*tr[x][1]==0) root=tr[x][0]+tr[x][1];
 57             else
 58               {
 59                   int k=tr[k][1];
 60                   while (tr[k][0]) k=tr[k][0];
 61                   tr[k][0]=tr[x][0];
 62                   fa[tr[x][0]]=k;
 63                   root=tr[x][1];
 64               }
 65     fa[root]=0;
 66     }
 67
 68 void ask_before(int k,int x)
 69    {
 70        if (k==0) return ;
 71        if (x>=num[k])
 72            {
 73               before=k;
 74            ask_before(tr[k][1],x);
 75            }
 76         else ask_before(tr[k][0],x);
 77    }
 78
 79 void ask_after(int k,int x)
 80    {
 81          if (k==0) return ;
 82          if (x<=num[k])
 83             {
 84                 after=k;
 85                 ask_after(tr[k][0],x);
 86             }
 87         else ask_after(tr[k][1],x);
 88        }
 89
 90 int main()
 91   {
 92       scanf("%d",&n);
 93     int f,x;
 94       for (int i=0;i<n;i++)
 95       {
 96         scanf("%d%d",&f,&x);
 97         if (!root)
 98         {
 99          kind=f;
100              ins(root,x,0);
101         }
102         else
103            if (f==kind) ins(root,x,0);
104                else
105                 {
106                   before=after=-1;
107                   ask_before(root,x);
108                   ask_after(root,x);
109                   if(before==-1){ans+=num[after]-x;ans%=1000000;del(after);}
110                       else if(after==-1){ans+=x-num[before];ans%=1000000;del(before);}
111                                 else
112                                     {
113                                         if(x-num[before]>num[after]-x)  {ans+=num[after]-x;ans%=1000000;del(after);}
114                                             else{ans+=x-num[before];ans%=1000000;del(before);}
115                                     }
116
117                 }
118      }
119     printf("%d",ans);
120   }
时间: 2024-11-04 19:34:00

C++之路进阶——splay树(宠物收养所)的相关文章

C++之路进阶——线段树(上帝造题的七分钟 2)

2492 上帝造题的七分钟 2 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作. 第三分钟,k说,要能查询,于是便有了求一段数的和的操作. 第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围. 第五分钟,诗人说,要有韵

c++之路进阶——treap树(普通平衡树)

4543 普通平衡树 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Description 这是一道水题 顺便祝愿LEZ和ZQQ 省选AKAKAK 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为小于x,且最大的数)6. 求x的后继(后继定义为大

bzoj1208 宠物收养所treap/splay/set

偷懒用set 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<set> 5 #include<algorithm> 6 #define rep(i,l,r) for(int i=l;i<r;i++) 7 #define update(a) (ans+=a)%=1000000 8 typedef long long ll; 9 using names

【BZOJ-1208】宠物收养所 Splay

1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6638  Solved: 2601[Submit][Status][Discuss] Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^

1208. [HNOI2004]宠物收养场【平衡树-splay】

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领养者

洛谷P2286宠物收养场

1 #include<cstdio> 2 #define abs(a,b) (a>b?a-b:b-a) 3 #define MOD 1000000 4 #define MXN 450000+5 5 int read(){ 6 int x=0,w=1; 7 char c=getchar(); 8 while(c<'0'||c>'9'){ 9 if(c=='-') w=-1; 10 c=getchar(); 11 } 12 while(c>='0'&&c&l

[bzoj1208][HNOI2004]宠物收养所

题目好长啊直接copy算了 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领

宠物收养所(bzoj1208)

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领养者

【bzoj1208】[HNOI2004]宠物收养所

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领养者