题解 P2286 【[HNOI2004]宠物收养场】
大家好,这个题我调了很久过了,所以想写题解
我用的平衡树是AVL树,平衡树界的老爷爷
这个树并不会很慢,主要是我初学,常数巨大
而且题目的 $ n = 80000$,可以接受
\(solution\):
开两颗平衡树,维护宠物和人,过多就插入自己的平衡树,过少就在对立平衡树中删除与 \(x\) 相差最小的。
也就是确定前驱后继
代码很长,但是操作是相同的,一半都是在复制粘贴
希望注意传参引用,少写一个调了很长时间
\(code:\)
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 80000+50;
const int mod = 1000000;
int ans;
inline void read(int &k) {
k=0;char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch<='9'&&ch>='0') k=k*10+ch-'0',ch=getchar();
}
namespace pet{
int root,cnt;
struct node{
int l,r,val,height,size;
}avl[N];
inline void newnode(int &now,int val) {
avl[now=++cnt].val=val,avl[now].size=1;
}
int factor(int now) {
return avl[avl[now].l].height-avl[avl[now].r].height;
}
void update(int now) {
avl[now].size=avl[avl[now].l].size+avl[avl[now].r].size+1;
avl[now].height=max(avl[avl[now].l].height,avl[avl[now].r].height)+1;
}
void zag(int &now) {
int r=avl[now].r;
avl[now].r=avl[r].l;
avl[r].l=now;
now=r;
update(avl[now].l),update(now);
}
void zig(int &now) {
int l=avl[now].l;
avl[now].l=avl[l].r;
avl[l].r=now;
now=l;
update(avl[now].r),update(now);
}
void check(int &now) {
int bf=factor(now);
if(bf>1) {
int lf=factor(now);
if(lf>0) zig(now);
else zag(avl[now].l),zig(now);
}else if(bf<-1) {
int rf=factor(now);
if(rf<0) zag(now);
else zig(avl[now].r),zag(now);
}else if(now) update(now);
}
void ins(int &now,int val) {
if(!now) newnode(now,val);
else if(avl[now].val>val) ins(avl[now].l,val);
else ins(avl[now].r,val);
check(now);
}
int find(int &now,int fa) {
int tmp;
if(!avl[now].l) tmp=now,avl[fa].l=avl[now].r;
else tmp=find(avl[now].l,now),check(now);
return tmp;
}
void del(int &now,int val) {
if(avl[now].val==val) {
int l=avl[now].l,r=avl[now].r;
if(!l||!r) now=l+r;
else {
now=find(r,r);
if(now!=r) avl[now].r=r;
avl[now].l=l;
}
}else if(avl[now].val>val) del(avl[now].l,val);
else del(avl[now].r,val);
check(now);
}
int getrank(int val) {
int now=root,rank=1;
while(now) {
if(val<=avl[now].val) now=avl[now].l;
else rank+=avl[avl[now].l].size+1,now=avl[now].r;
}
return rank;
}
int getnum(int rank) {
int now=root;
while(now) {
if(rank==avl[avl[now].l].size+1) break;
else if(rank<=avl[avl[now].l].size) now=avl[now].l;
else rank-=avl[avl[now].l].size+1,now=avl[now].r;
}
return avl[now].val;
}
int search(int now,int val) {
if(!now) return false;
if(val==avl[now].val) return true;
else if(val<avl[now].val) return search(avl[now].l,val);
else return search(avl[now].r,val);
return false;
}
}
namespace human{
int root,cnt;
struct node{
int l,r,val,height,size;
}avl[N];
inline void newnode(int &now,int val) {
avl[now=++cnt].val=val,avl[now].size=1;
}
int factor(int now) {
return avl[avl[now].l].height-avl[avl[now].r].height;
}
void update(int now) {
avl[now].size=avl[avl[now].l].size+avl[avl[now].r].size+1;
avl[now].height=max(avl[avl[now].l].height,avl[avl[now].r].height)+1;
}
void zag(int &now) {
int r=avl[now].r;
avl[now].r=avl[r].l;
avl[r].l=now;
now=r;
update(avl[now].l),update(now);
}
void zig(int &now) {
int l=avl[now].l;
avl[now].l=avl[l].r;
avl[l].r=now;
now=l;
update(avl[now].r),update(now);
}
void check(int &now) {
int bf=factor(now);
if(bf>1) {
int lf=factor(now);
if(lf>0) zig(now);
else zag(avl[now].l),zig(now);
}else if(bf<-1) {
int rf=factor(now);
if(rf<0) zag(now);
else zig(avl[now].r),zag(now);
}else if(now) update(now);
}
void ins(int &now,int val) {
if(!now) newnode(now,val);
else if(avl[now].val>val) ins(avl[now].l,val);
else ins(avl[now].r,val);
check(now);
}
int find(int &now,int fa) {
int tmp;
if(!avl[now].l) tmp=now,avl[fa].l=avl[now].r;
else tmp=find(avl[now].l,now),check(now);
return tmp;
}
void del(int &now,int val) {
if(avl[now].val==val) {
int l=avl[now].l,r=avl[now].r;
if(!l||!r) now=l+r;
else {
now=find(r,r);
if(now!=r) avl[now].r=r;
avl[now].l=l;
}
}else if(avl[now].val>val) del(avl[now].l,val);
else del(avl[now].r,val);
check(now);
}
int getrank(int val) {
int now=root,rank=1;
while(now) {
if(val<=avl[now].val) now=avl[now].l;
else rank+=avl[avl[now].l].size+1,now=avl[now].r;
}
return rank;
}
int getnum(int rank) {
int now=root;
while(now) {
if(rank==avl[avl[now].l].size+1) break;
else if(rank<=avl[avl[now].l].size) now=avl[now].l;
else rank-=avl[avl[now].l].size+1,now=avl[now].r;
}
return avl[now].val;
}
int search(int now,int val) {
if(!now) return false;
if(val==avl[now].val) return true;
else if(val<avl[now].val) return search(avl[now].l,val);
else return search(avl[now].r,val);
return false;
}
}
signed main() {
int n; cin>> n;
while(n--) {
int opt, x;
// scanf("%lld%lld",&opt, &x);
read(opt),read(x);
if(!opt) {
if(human::avl[human::root].size) {
if(human::search(human::root,x)) human::del(human::root,x);
else {
int pre=human::getnum(human::getrank(x)-1);
int nxt=human::getnum(human::getrank(x+1));
if(pre==0) { ans+=nxt-x,ans%=mod,human::del(human::root,nxt);continue;}
if(nxt==0) { ans+=x-pre,ans%=mod,human::del(human::root,pre);continue;}
if(x-pre<=nxt-x) ans+=x-pre,ans%=mod,human::del(human::root,pre);
else ans+=nxt-x,ans%=mod,human::del(human::root,nxt);
}
}else pet::ins(pet::root,x);
}else {
if(pet::avl[pet::root].size) {
if(pet::search(pet::root,x)) pet::del(pet::root,x);
else {
int pre=pet::getnum(pet::getrank(x)-1);
int nxt=pet::getnum(pet::getrank(x+1));
if(pre==0) { ans+=nxt-x,ans%=mod,pet::del(pet::root,nxt);continue;}
if(nxt==0) { ans+=x-pre,ans%=mod,pet::del(pet::root,pre);continue;}
if(x-pre<=nxt-x) ans+=x-pre,ans%=mod,pet::del(pet::root,pre);
else ans+=nxt-x,ans%=mod,pet::del(pet::root,nxt);
}
}else human::ins(human::root,x);
}
}
cout<<ans;
return 0;
}
题解 P2286 【[HNOI2004]宠物收养场】的更多相关文章
- 洛谷P2286 [HNOI2004]宠物收养场【Treap】题解+AC代码
题目传送门啦~啦~啦~ 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的 ...
- P2286 [HNOI2004]宠物收养场
题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
- 洛谷P2286 [HNOI2004]宠物收养场
题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
- 洛谷 P2286 [HNOI2004]宠物收养场
题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
- Luogu P2286 [HNOI2004]宠物收养场
一道比较简单的直接Treap运用题目,思维难度和代码难度都不是很高. 题意有点长,我们仔细剖析一下题意发现以下几个关键: 任何时候收养站里只可能有人和宠物中的其中一种,或者都没有 如果只有宠物并有人来 ...
- 【题解】 [HNOI2004]宠物收养场(Splay)
懒得复制,戳我戳我 Solution: \(Splay\)板子,注意交换的地方,然后就是注意不要越界node[x],应该是\(node[now]\),其次就是数组可以开大点 Code: //It is ...
- [HNOI2004]宠物收养场 Treap前驱后继
凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领 ...
- 洛谷P2286 [HNOI2004]宠物收养所 [STL,平衡树]
题目传送门 宠物收养所 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的 ...
- BZOJ1208[HNOI2004]宠物收养场——treap
凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领 ...
- [HNOI2004]宠物收养场 BZOJ1208 splay tree
题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
随机推荐
- Redis KeyExpire的使用
Set a timeout on key. After the timeout has expired, the key will automatically be deleted. A key wi ...
- linux自定义开机欢迎页面图案
1:编辑etc目录下motd文件 佛祖图案 [root@host1 ~]# vim /etc/motd _oo0oo_ 088888880 88" . "88 (| -_- |) ...
- nginx之 nginx限流配置
limit_req zone=req_zone;严格依照在limti_req_zone中配置的rate来处理请求超过rate处理能力范围的,直接drop表现为对收到的请求无延时limit_req zo ...
- 《Java基础知识》Java断言
断言:也就是所谓的assertion,是jdk1.4后加入的新功能. 它主要使用在代码开发和测试时期,用于对某些关键数据的判断,如果这个关键数据不是你程序所预期的数据,程序就提出警告或退出. 当软件正 ...
- python错误调试print、assert、logging、pdb、pdb.set_trace()
世界人都知道,程序总会有bug存在.复杂点的bug一般人不能一眼看出,这就一要一套调试程序的手段. 方法一:使用print()函数直接打印: >>> def foo(s): ... ...
- 对JDK动态代理的模拟实现
对JDK动态代理的模拟 动态代理在JDK中的实现: IProducer proxyProduec = (IProducer)Proxy.newProxyInstance(producer.getCla ...
- vue组件初始化过程
之前文章有写到vue构造函数的实例化过程,只是对vue实例做了个粗略的描述,并没有说明vue组件实例化的过程.本文主要对vue组件的实例化过程做一些简要的描述. 组件的实例化与vue构造函数的实例化, ...
- Gradle-任务
任务结果标签 当 Gradle 执行一个任务时,它会在控制台和 Tooling API 根据任务结果给任务打标签. 这些标签是根据任务是否有操作,是否应该执行操作,是否执行了操作以及这些操作做了哪些改 ...
- Qt在Android平台上实现html转PDF的功能
Qt for Android Qt for Android enables you to run Qt 5 applications Android devices. All Qt modules ( ...
- 为什么delete后磁盘空间没有释放而truncate会释放?
背景 因项目需求,需要清理一批旧数据,腾出空间给新数据,让同事负责这件事.料想会很顺利,但很快找到我,并告知在postgresql中把一张大的数据表删除掉了,查询表的size并没有改变. 我震惊了,问 ...