【传送门】

前言

这一篇题解并不是为了讲什么算法,只是总结一下平衡树在OI考试中的注意事项。

题意简化(给不想看题目的小伙伴们一点福利)

给你两堆数,每一次给你一个数,每一次在另外一堆数中找到这个数的前缀后继,删去前驱后继中较靠近的,得到了分数为两个数的差的绝对值。请你让这个分数最小。
(题意简化的应该不能在简化了吧qwq)


做法1&&2&&3(非正常做法)

我们都知道,所有的平衡树的题目都可以用不定长数组vector和不允许重复元素的set或者是允许重复元素的muliset来实现。
这个东西在考场上是救命的,如果你剩下的时间不多了,那么是在不行就用以上的办法来偏分。
分析一下vectorsetmuliset的优缺点。
不定长数组vector实现起来非常的简单,只要你熟悉指针和vector的正常操作。
但是vector很容易溢出,长度一大,很有可能就RE,那个时候想哭都没时间哭了。

#include <bits/stdc++.h>
using namespace std;
int n;
vector<int>v;
int main() {scanf("%d",&n);for(int i=1;i<=n;i++) {int op=0,x=0;scanf("%d%d",&op,&x);if(op==1) v.insert(upper_bound(v.begin(),v.end(),x),x);else if(op==2) v.erase(lower_bound(v.begin(),v.end(),x));else if(op==3) printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1);else if(op==4) printf("%d\n",v[x-1]);else if(op==5) printf("%d\n",*--lower_bound(v.begin(),v.end(),x));else if(op==6) printf("%d\n",*upper_bound(v.begin(),v.end(),x));}return 0;
}

实现非常的简单,但是需要注意指针的变换。
但是这一道题目我们用vector,蒟蒻我用了差不多5s才跑出大的数据。(数据从LOJ上来的)
所以setmuliset可以更加快速的完成我们的任务。
set差别并不是太大,一个可以实现没有重复的,一个实现有重复的。
来自chhokmah的实测,set比muliset要快。
所以总结一下:

  • vector好写,但是容易错,不推荐使用。
  • set可以实现无重复,推荐使用。
  • muliset可以实现有重复,推荐使用。

做法4正常的平衡树

这里以treap为例。
简单介绍一下treap,treap是tree和heap的结合,每一次我们需要用自己给节点附加的rd值来维护平衡树的平衡性。
代码实现非常的简单,但是我打的比较冗长。
那么再回到这一道题目,如果我们只需要建立两个平衡树。(其实一棵就足够了,因为一棵有节点的时候另外一棵一定是没有节点的。)
每一次找前驱和后继,判断更加接近的那一个,更新答案,并删除前驱或者是后继。
如果树为空或者是己方的树有节点,那么就直接插入。

#include <bits/stdc++.h>
#define N 80005
#define mod 1000000
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
template <typename T>
inline void read(T &x) {x = 0; T fl = 1; char ch = 0;for (; ch < '0' || ch > '9'; ch = getchar())if (ch == '-') fl = -1;for (; ch >= '0' && ch <= '9'; ch = getchar())x = (x << 1) + (x << 3) + (ch ^ 48);x *= fl;
}
struct Treap {int tot, rt;struct Node {int cnt, sz, rd, ch[2], val;void Init (int Val) { val = Val; ch[0] = ch[1] = 0; cnt = sz = 1; rd = rand() % 100; } } tr[N];Treap() { tot = 0; memset(tr, 0, sizeof(tr)); }void pushup (int nod) { tr[nod].sz = tr[tr[nod].ch[0]].sz + tr[tr[nod].ch[1]].sz + tr[nod].cnt; }void rotate(int &nod, int d) {int k = tr[nod].ch[d ^ 1]; tr[nod].ch[d ^ 1] = tr[k].ch[d]; tr[k].ch[d] = nod;pushup(nod); pushup(k); nod = k;}void ins(int &nod, int val) {if (!nod) nod = ++ tot, tr[nod].Init(val);else if (val == tr[nod].val) tr[nod].sz ++, tr[nod].cnt ++;else {int d = (val > tr[nod].val);ins(tr[nod].ch[d], val); if (tr[nod].rd < tr[tr[nod].ch[d]].rd) rotate(nod, d ^ 1);pushup(nod);}}void del(int &nod, int val) {if (!nod) return;if (val < tr[nod].val) del(tr[nod].ch[0], val);else if (val > tr[nod].val) del(tr[nod].ch[1], val);else {if (!tr[nod].ch[0] && !tr[nod].ch[1]) {tr[nod].sz --, tr[nod].cnt --; if (tr[nod].cnt == 0) nod = 0;}else if (tr[nod].ch[0] && !tr[nod].ch[1]) { rotate(nod, 1) ; del(tr[nod].ch[1], val);} else if (!tr[nod].ch[0] && tr[nod].ch[1]) { rotate(nod, 0); del(tr[nod].ch[0], val); }else {int d = tr[tr[nod].ch[0]].rd > tr[tr[nod].ch[1]].rd;rotate(nod, d); del(tr[nod].ch[d], val);}}}int pre(int nod, int val) {if (!nod) return -inf;if (tr[nod].val > val) return pre(tr[nod].ch[0], val);else return max(tr[nod].val , pre(tr[nod].ch[1], val));} int suc(int nod, int val) {if (!nod ) return inf;if (tr[nod].val < val) return suc(tr[nod].ch[1], val);else return min(tr[nod].val, suc(tr[nod].ch[0], val));}
}Pet, Cus;
int n;
ll ans = 0ll;
int main () {srand(19260817);read(n);while (n --) {int opt, x; read(opt); read(x);if (opt == 0) { // Petif (Cus.rt == 0) Pet.ins(Pet.rt, x);else {int lst = Cus.pre(Cus.rt, x), nxt = Cus.suc(Cus.rt, x);if (abs(x - lst) <= abs(nxt - x))  { Cus.del(Cus.rt, lst); ans = (ans + 1ll * abs(x - lst)) % mod; }else { Cus.del(Cus.rt, nxt); ans = (ans + 1ll * abs(nxt - x)) % mod;}}}else { // Customerif (Pet.rt == 0) Cus.ins(Cus.rt, x);else {int lst = Pet.pre(Pet.rt, x), nxt = Pet.suc(Pet.rt, x);if (abs(x - lst) <= abs(nxt - x))  { Pet.del(Pet.rt, lst); ans = (ans + 1ll * abs(x - lst)) % mod; }else { Pet.del(Pet.rt, nxt); ans = (ans + 1ll * abs(nxt - x)) % mod;}}}}printf("%lld\n", ans % mod);return 0;
}

转载于:https://www.cnblogs.com/chhokmah/p/10643211.html

[luogu2286][HNOI2004]宠物收养场【平衡树】相关推荐

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

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

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

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

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

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

  4. B1208 [HNOI2004]宠物收养所 平衡树||set (滑稽)

    这个题是一道splay裸题,但是我不太会写,所以用set直接水过去!!!哈哈哈哈,美滋滋. set总结: set是一个集合,然后里面没用重复的元素.里面有一些函数: begin()     ,返回se ...

  5. [HNOI2004]宠物收养场

    嘟嘟嘟 看完题,思路一秒就出来了:建两棵平衡树,分别维护宠物和领养者.然后就是正常的插入,找前驱后继,删除操作了. 然后旁边的lba巨佬说只用建一棵就行,如果宠物多了就维护宠物,否则维护领养者. 总而 ...

  6. P2286 [HNOI2004]宠物收养场

    我是题面 题意简单明了,两种数,如果加入一个数的时候有另一种数还存在,那就取出另一种数中与这个数差值的绝对值最小的将其删除(多个则取较小),并对答案产生它们差值的绝对值的贡献,如果没有另一种数存在,那 ...

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

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

  8. cogs62 [HNOI2004] 宠物收养所

    cogs62 [HNOI2004] 宠物收养所 啦啦啦啦 不维护区间的平衡树题都是树状数组+二分练手题! 不会的参考我的普通平衡树的多种神奇解法之BIT+二分答案 // It is made by X ...

  9. BZOJ 1208: [HNOI2004]宠物收养所

    1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7684  Solved: 3042 [Submit][S ...

最新文章

  1. card2phone android,Installing application on SD-card in Android sdk 2.2
  2. ActiveMQ点对点的发送和接收
  3. 《剑指offer》连续子数组的最大和
  4. gcc和g++有什么区别?
  5. 机器学习模型可解释性进行到底 ——PDPICE图(三)
  6. 编译OpenJDK12:globalDefinitions_visCPP.hpp(46): fatal error C1083:inttypes.h No such file or directory
  7. 二叉搜索树的根插入、选择、删除、合并、排序等操作的实现
  8. javaEE之----------java代码发送邮件
  9. LabWindows操作SQL SERVER
  10. Gauss 求积公式及代码
  11. 软件测试入门知识,Linux系统基础教程——带你玩转Linux(五)
  12. Micropython教程之TPYBoard DIY电子时钟(萝卜学科编程教育)
  13. gtk设计简单的文本编辑器(1)
  14. BUUCTF-Misc-No.4
  15. 交叉编译arm版linaro-1.13.1-4.7-2013.03
  16. 运维岗位面试被问到的问题
  17. 迅为iTop4412精英板运行QT程序触摸/鼠标失灵
  18. linux kill进程 不发送fin,linux – FIN省略,FIN-ACK发送
  19. 基于预训练语言模型的检索- 匹配式知识图谱问答系统
  20. 轴承热处理,你了解吗?

热门文章

  1. dotnet-cli命令小结
  2. Visual Studio 2019 16.2.2 发布
  3. linux c 语言 errno 我个头,Linux错误代码:errno.h与返回值 -EINVAL
  4. mysql下拉框回显_下拉框的回显 (修改时候)
  5. element-ui upload组件 上传文件类型限制
  6. Google Chrome进入暗黑模式
  7. linux clang安装,linux 配置 clang++ SDL 开发环境 (新手向)
  8. mysql 复制 错误_Mysql复制错误error
  9. 功能安全 李艳文_中国汽车功能安全测试库首次成果发布会成功召开
  10. linux系统获取光盘信息api,在Visual C#中运用API函数获取系统信息