HYSBZ 1208 宠物收养所 (Splay树)
题意:一家宠物收养所负责处理领养者与遗弃宠物业务,有人来领宠物,则领一只最理想的。若没有宠物了,领养者们就得等到宠物来,宠物一来立刻送给其中一个等待者。如果有两个理想的选择,则选择那个值较小的。收养所时刻只存在人or宠物or没有存在任何!
思路:
这题主要是树中可能存在人或者宠物,但两者不可能同时存在,因为一旦存在,必须有对象被配对并从树中删除。 所有函数独自写起来都是很简单的,但是合起来使用时就得小心了,得配合一点。
要时刻注意树中是否还有节点,若没有,则可能要树要换种类了。
#include <bits/stdc++.h>
#define pii pair<int,int>
#define INF 0x3f7f7f7f
#define LL long long
using namespace std;
const int N=;
const int mod=; struct node
{
int key, pre, ch[];
}nod[N];
int node_cnt, root, flag; int create_node(int v,int far)
{
nod[node_cnt].ch[]=nod[node_cnt].ch[]=;
nod[node_cnt].pre=far;
nod[node_cnt].key=v;
return node_cnt++;
} void Rotate(int t,int d)
{
int son=nod[t].ch[d];
int far=nod[t].pre;
int gra=nod[far].pre;
nod[t].pre=gra;
nod[far].pre=t;
nod[son].pre=far;
nod[t].ch[d]=far;
nod[far].ch[d^]=son;
nod[gra].ch[ nod[gra].ch[]==far ]=t;
} int Insert(int t,int v)
{
if(t==) return root=create_node(v, ); //树中还没有节点。
if( v < nod[t].key )
{
if(nod[t].ch[]) return Insert(nod[t].ch[], v);
else return nod[t].ch[]=create_node(v, t);
}
else
{
if(nod[t].ch[]) return Insert(nod[t].ch[], v);
else return nod[t].ch[]=create_node(v, t);
}
} void Splay(int t, int goal)
{
while(nod[t].pre!=goal)
{
int f=nod[t].pre, g=nod[f].pre;
if(g==goal) Rotate( t, nod[f].ch[]==t );
else
{
int d1=nod[f].ch[]==t, d2=nod[g].ch[]==f;
if(d1==d2) Rotate(f, d1),Rotate(t, d1);
else Rotate(t, d1),Rotate(t, d2);
}
}
if(goal==) root=t; //随时更新根!
} int Find(int t,int v) //在子树t中找到值为v的点,返回点号
{
while(t)
{
if(v==nod[t].key) return t;
if(v<nod[t].key) t=nod[t].ch[];
else t=nod[t].ch[];
}
return ; //找不到
} int Find_pre(int t,int v)
{
int val=-;
while(t)
{
if(nod[t].key<v) val=max(val, nod[t].key);
if(v<nod[t].key) t=nod[t].ch[];
else t=nod[t].ch[];
}
if(val<) return INF;
return val;
} int Find_bac(int t,int v)
{
int val=INF;
while(t)
{
if(nod[t].key>v) val=min(val, nod[t].key);
if(v<nod[t].key) t=nod[t].ch[];
else t=nod[t].ch[];
}
return val;
} void Delete(int v) //在树中删除值为v的任意一个点
{
Splay(Find(root, v), ); //将目标旋转到根
int L=nod[root].ch[];
int R=nod[root].ch[];
if(L== && R==) root=;
else if(R==) //没有右子树
{
nod[L].pre=;
root=L;
}
else if(L==) //没有左子树
{
nod[R].pre=;
root=R;
}
else //有前有后
{
while(nod[R].ch[]) R=nod[R].ch[]; //找到后继
Splay(R, root);
nod[R].ch[]=L;
nod[R].pre=;
nod[L].pre=R;
root=R;
}
} int main()
{
//freopen("input.txt", "r", stdin);
int n, ans, a, b, contain;
while(cin>>n)
{
flag=node_cnt=;
contain=root=ans=;
while(n--)
{
scanf("%d%d",&a,&b);
if(a==flag || contain==) // 树为空 or 树中是同种类 则 插入
{
flag=a;
contain++;
Splay(Insert(root, b), );
}
else
{
if(Find(root, b)) Delete(b); //刚好有值为b的。
else
{
int L=Find_pre(root, b);
int R=Find_bac(root, b);
if( abs(L-b)<=abs(R-b) ) //L和R不可能同时为INF。
{
ans=(ans+abs(L-b))%mod;
Delete(L);
}
else
{
ans=(ans+abs(R-b))%mod;
Delete(R);
}
}
contain--;
}
}
printf("%d\n", ans );
}
return ;
}
AC代码
HYSBZ 1208 宠物收养所 (Splay树)的更多相关文章
- bzoj 1208 宠物收养所--splay
这个题也是单点维护,不管来的是人还是狗,只要num=0就插入,否则就删除. // File Name: ACM/bzoj/1208.cpp // Author: Zlbing // Created T ...
- BZOJ 1208 宠物收养所 | 平衡树模板题
BZOJ 1208 宠物收养所 我犯过的错误:删除一个节点后没有update新的根节点,导致size错了! #include <cstdio> #include <cmath> ...
- Bzoj 1208: [HNOI2004]宠物收养所(splay)
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MB Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收 ...
- 【BZOJ-1208】宠物收养所 Splay
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6638 Solved: 2601[Submit][Sta ...
- 【BZOJ1208】[HNOI2004]宠物收养所 Splay
还是模板题,两颗splay,找点删即可. #include <iostream> #include <cstdio> #include <cstdlib> #def ...
- BZOJ 1208 宠物收养所
Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特 ...
- BZOJ 1208 宠物收养所 set+二分
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1208 题目大意: 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠 ...
- [bzoj1208][HNOI2004]宠物收养所——splay
题目大意 Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发 ...
- HNOI2004宠物收养所(splay维护二叉搜索树模板题)
描述 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
随机推荐
- LA-3905 (扫描线)
题意: 给一些流星的初始位置和运动向量,给了相机的拍摄范围;问你最多能拍到多少颗流星; 思路: 将流星用出现在相机拍摄范围内的时间段表示;sort后在扫面端点更新最大值; Ac代码: #include ...
- 4种java复制文件的方式
尽管Java提供了一个可以处理文件的IO操作类,但是没有一个复制文件的方法.复制文件是一个重要的操作,当你的程序必须处理很多文件相关的时候.然而有几种方法可以进行Java文件复制操作,下面列举出4中最 ...
- E20170426-gg
recursive adj. 回归的,递归的; removal n. 除去; 搬迁; 免职; 移走; customize vt. 定制,定做; 按规格改制;
- Codeforces Round #357 (Div. 2)C. Heap Operations
用单调队列(从小到大),模拟一下就好了,主要是getMin比较麻烦,算了,都是模拟....也没什么好说的.. #include<cstdio> #include<map> #i ...
- CF767E ChangeFree【贪心/优先队列】By cellur925
题目传送门 $naive$想法 最开始的一个贪心策略是每次尽量花掉硬币 ,如果不满足条件,就花纸币.而且不满足条件的时候,要尽量向百取整.(显然是不对的,因为有时候不够)但是显然这个贪心策略是错误的, ...
- js同过url下载文件,调用另存为弹框
实战中,项目将文件上传到项目的根目录下,并进行保存,随后根据此文件的路径进行下载到本地磁盘 实战中,项目将文件上传到项目的根目录下,并进行保存,随后根据此文件的路径进行下载到本地磁盘 实战中,项目将文 ...
- 大数模板 (C ++)
上次BC遇到一个大数题目,没有大数模板和不会使用JAVA的同学们GG了,赛后从队友哪里骗出大数模板.2333333,真的炒鸡nice(就是有点长),贴出来分享一下好辣. //可以处理字符串前导零 #i ...
- sql 语句操作,修改字段中字符串的一部分
update 表名 set 字段=replace(字段,‘替换的部分’,‘替换后的字符串’): update 表名 set A=replace( A, '海淀', '朝阳') where A like ...
- 创建表规范 lob 字段
ORAClce 11g 提供如下特性: BasicfileOracle10g 及之前版本被称为basicfile Securefile11g中新增securefile 优点:集中写入缓存(WGC),4 ...
- 通过表单展示不一样的页面(input对象)
表单中包含不一样的样式,不同功能的提交数据的方式.在许多页面中,浏览者不经意间已经不断在使用表单的功能,如留言,设置自己的密码或者是复选框,下拉列表等. input对象下的多种表单表现形式: 通常在页 ...