一道比较简单的直接Treap运用题目,思维难度和代码难度都不是很高。

题意有点长,我们仔细剖析一下题意发现以下几个关键:

  1. 任何时候收养站里只可能有人和宠物中的其中一种,或者都没有
  2. 如果只有宠物并有人来时,那个人会立刻挑选一只宠物并离开(只有人的时候同理)。
  3. 如果没有宠物并有人来时,那个人会一直等着直到有宠物到来并且那个宠物被它领养了(没有人的时候同理)。

然后我们思考一下那个选宠物(或者是宠物选人)的过程,其实就是在一个集合找一个数和它最接近的过程。

然后这道题已经很良心地提示你了:

存在两个宠物a-b,a+b......

其实仔细想一下就是一个找前驱找后缀的问题,我们找出前驱和后继就可以直接统计并删除了。

具体实现的时候开两个Treap,一棵存宠物,一棵存人(这里由于宠物和人只会同时存在一种,所以其实开一棵也可以),然后按题意搞一下就可以了。

然后我写了两个namespace,所以主程序看上去有点乱。

最后注意开long long

CODE

  1. #include<cstdio>
  2. #include<cctype>
  3. using namespace std;
  4. typedef long long LL;
  5. const LL N=80005,INF=1e18,mod=1000000;
  6. LL n,opt,x,ans;
  7. inline char tc(void)
  8. {
  9. static char fl[100000],*A=fl,*B=fl;
  10. return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
  11. }
  12. inline void read(LL &x)
  13. {
  14. x=0; char ch; while (!isdigit(ch=tc()));
  15. while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
  16. }
  17. inline LL rand(void)
  18. {
  19. static LL seed=233;
  20. return seed=(LL)seed*482711LL%2147483647;
  21. }
  22. inline LL min(LL a,LL b)
  23. {
  24. return a<b?a:b;
  25. }
  26. namespace pet
  27. {
  28. struct Treap
  29. {
  30. LL ch[2],val,dat;
  31. }node[N];
  32. LL tot,rt,size;
  33. inline LL build(LL v)
  34. {
  35. node[++tot].val=v; node[tot].dat=rand(); return tot;
  36. }
  37. inline void init(void)
  38. {
  39. rt=build(-INF); node[rt].ch[1]=build(INF);
  40. }
  41. inline void rotate(LL &rt,LL d)
  42. {
  43. LL temp=node[rt].ch[d^1]; node[rt].ch[d^1]=node[temp].ch[d];
  44. node[temp].ch[d]=rt; rt=temp;
  45. }
  46. inline void insert(LL &rt,LL v)
  47. {
  48. if (!rt) { rt=build(v); return; }
  49. LL d=v<node[rt].val?0:1; insert(node[rt].ch[d],v);
  50. if (node[rt].dat<node[node[rt].ch[d]].dat) rotate(rt,d^1);
  51. }
  52. inline void remove(LL &rt,LL v)
  53. {
  54. if (node[rt].val==v)
  55. {
  56. if (node[rt].ch[0]||node[rt].ch[1])
  57. {
  58. if (!node[rt].ch[1]||node[node[rt].ch[1]].dat<node[node[rt].ch[0]].dat) rotate(rt,1),remove(node[rt].ch[1],v);
  59. else rotate(rt,0),remove(node[rt].ch[0],v);
  60. } else rt=0; return;
  61. }
  62. if (v<node[rt].val) remove(node[rt].ch[0],v); else remove(node[rt].ch[1],v);
  63. }
  64. inline LL get_pre(LL rt,LL v)
  65. {
  66. LL pre;
  67. while (rt)
  68. {
  69. if (node[rt].val<=v) pre=node[rt].val,rt=node[rt].ch[1];
  70. else rt=node[rt].ch[0];
  71. }
  72. return pre;
  73. }
  74. inline LL get_next(LL rt,LL v)
  75. {
  76. LL next;
  77. while (rt)
  78. {
  79. if (node[rt].val>=v) next=node[rt].val,rt=node[rt].ch[0];
  80. else rt=node[rt].ch[1];
  81. }
  82. return next;
  83. }
  84. };
  85. namespace hum
  86. {
  87. struct Treap
  88. {
  89. LL ch[2],val,dat;
  90. }node[N];
  91. LL tot,rt,size;
  92. inline LL build(LL v)
  93. {
  94. node[++tot].val=v; node[tot].dat=rand(); return tot;
  95. }
  96. inline void init(void)
  97. {
  98. rt=build(-INF); node[rt].ch[1]=build(INF);
  99. }
  100. inline void rotate(LL &rt,LL d)
  101. {
  102. LL temp=node[rt].ch[d^1]; node[rt].ch[d^1]=node[temp].ch[d];
  103. node[temp].ch[d]=rt; rt=temp;
  104. }
  105. inline void insert(LL &rt,LL v)
  106. {
  107. if (!rt) { rt=build(v); return; }
  108. LL d=v<node[rt].val?0:1; insert(node[rt].ch[d],v);
  109. if (node[rt].dat<node[node[rt].ch[d]].dat) rotate(rt,d^1);
  110. }
  111. inline void remove(LL &rt,LL v)
  112. {
  113. if (node[rt].val==v)
  114. {
  115. if (node[rt].ch[0]||node[rt].ch[1])
  116. {
  117. if (!node[rt].ch[1]||node[node[rt].ch[1]].dat<node[node[rt].ch[0]].dat) rotate(rt,1),remove(node[rt].ch[1],v);
  118. else rotate(rt,0),remove(node[rt].ch[0],v);
  119. } else rt=0; return;
  120. }
  121. if (v<node[rt].val) remove(node[rt].ch[0],v); else remove(node[rt].ch[1],v);
  122. }
  123. inline LL get_pre(LL rt,LL v)
  124. {
  125. LL pre;
  126. while (rt)
  127. {
  128. if (node[rt].val<=v) pre=node[rt].val,rt=node[rt].ch[1];
  129. else rt=node[rt].ch[0];
  130. }
  131. return pre;
  132. }
  133. inline LL get_next(LL rt,LL v)
  134. {
  135. LL next;
  136. while (rt)
  137. {
  138. if (node[rt].val>=v) next=node[rt].val,rt=node[rt].ch[0];
  139. else rt=node[rt].ch[1];
  140. }
  141. return next;
  142. }
  143. };
  144. int main()
  145. {
  146. //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
  147. pet::init(); hum::init(); read(n);
  148. while (n--)
  149. {
  150. read(opt); read(x);
  151. if (opt)
  152. {
  153. if (pet::size)
  154. {
  155. LL pre=pet::get_pre(pet::rt,x),next=pet::get_next(pet::rt,x); --pet::size;
  156. if (pre==-INF||x-pre>next-x) ans=(ans+next-x)%mod,pet::remove(pet::rt,next);
  157. else ans=(ans+x-pre)%mod,pet::remove(pet::rt,pre);
  158. } else ++hum::size,hum::insert(hum::rt,x);
  159. } else
  160. {
  161. if (hum::size)
  162. {
  163. LL pre=hum::get_pre(hum::rt,x),next=hum::get_next(hum::rt,x); --hum::size;
  164. if (pre==-INF||x-pre>next-x) ans=(ans+next-x)%mod,hum::remove(hum::rt,next);
  165. else ans=(ans+x-pre)%mod,hum::remove(hum::rt,pre);
  166. } else ++pet::size,pet::insert(pet::rt,x);
  167. }
  168. }
  169. return printf("%lld",ans),0;
  170. }

Luogu P2286 [HNOI2004]宠物收养场的更多相关文章

  1. P2286 [HNOI2004]宠物收养场

    题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  2. 洛谷P2286 [HNOI2004]宠物收养场【Treap】题解+AC代码

    题目传送门啦~啦~啦~ 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的 ...

  3. 洛谷P2286 [HNOI2004]宠物收养场

    题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  4. 洛谷 P2286 [HNOI2004]宠物收养场

    题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  5. 洛谷P2286 [HNOI2004]宠物收养所 [STL,平衡树]

    题目传送门 宠物收养所 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的 ...

  6. [HNOI2004]宠物收养场 Treap前驱后继

    凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领 ...

  7. BZOJ1208[HNOI2004]宠物收养场——treap

    凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领 ...

  8. [HNOI2004]宠物收养场 BZOJ1208 splay tree

    题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  9. LG_2286_[HNOI2004]宠物收养场

    题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

随机推荐

  1. 《Inside C#》笔记(二) 初识C#

    一 程序的编译.构成 a) 编写C#代码一般用VS,但作者在这儿介绍了使用记事本编写C#代码并编译运行的过程,以便对VS有更深入的认识. 用记事本编写C#代码后,修改文本文件的后缀为.cs,然后用cs ...

  2. Kotlin入门(7)循环语句的操作

    上一篇文章介绍了简单分支与多路分支的实现,控制语句除了这两种条件分支之外,还有对循环处理的控制,那么本文接下来继续阐述Kotlin如何对循环语句进行操作. Koltin处理循环语句依旧采纳了for和w ...

  3. 利用搜狐新闻语料库训练100维的word2vec——使用python中的gensim模块

    关于word2vec的原理知识参考文章https://www.cnblogs.com/Micang/p/10235783.html 语料数据来自搜狐新闻2012年6月—7月期间国内,国际,体育,社会, ...

  4. Linux下修改IP、DNS、路由命令行设置

    本文最后修改时间:20180313 一.快速修改,重启后设置就没了 ifconfig eth0 192.168.1.22 netmask 255.255.255.0 up route add defa ...

  5. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

  6. 用U盘制作EXSI启动盘

    用U盘制作EXSI启动盘这是一个比较困难的事,一般的人会用UltraISO这个软件来制作.但是很遗憾,这样的方法很不好,我试了好几次都没有成功.主要是不能引导. 之后我换了一个刻录软件(rufus), ...

  7. Json Schema的使用

    直接上案例: 在Web Api通讯中,客户端发送json数据,服务端反序列化json(json与某个类形成对应关系),在某些情况下,需要校验其上传的json是否合法. 服务端是使用Json.net(n ...

  8. 第七章 Hyper-V 2012 R2 授权管理

    当企业或组织的规模越来越大时,维护某一项单独的应用可能会由特定的运维人员进行管理.考虑到安全风险的问题,一般特定的运维人员不会拥有域管理员权限.自 Windows Server 2012 开始,操作系 ...

  9. linux kernel 源码安装

    有时我们在安装系统后,发现没有安装当前系统的内核源码在/usr/src/kernels目录下,其实我们是少安装了一个rpm包: 当你配置好yum源后: yum install kernel-devel ...

  10. U盘内容被病毒隐藏的解决办法(亲测可用)

    前几天用U盘的时候不小心感染上了病毒,用自己的电脑打开后里面只剩下一个U盘的快捷方式,选中显示隐藏文件之后依然没有任何显示,但是查看U盘的属性的时候可以看到,U盘已经使用了300多M,所以就上网查了一 ...