题意:一家宠物收养所负责处理领养者与遗弃宠物业务,有人来领宠物,则领一只最理想的。若没有宠物了,领养者们就得等到宠物来,宠物一来立刻送给其中一个等待者。如果有两个理想的选择,则选择那个值较小的。收养所时刻只存在人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树)的更多相关文章

  1. bzoj 1208 宠物收养所--splay

    这个题也是单点维护,不管来的是人还是狗,只要num=0就插入,否则就删除. // File Name: ACM/bzoj/1208.cpp // Author: Zlbing // Created T ...

  2. BZOJ 1208 宠物收养所 | 平衡树模板题

    BZOJ 1208 宠物收养所 我犯过的错误:删除一个节点后没有update新的根节点,导致size错了! #include <cstdio> #include <cmath> ...

  3. Bzoj 1208: [HNOI2004]宠物收养所(splay)

    1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MB Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收 ...

  4. 【BZOJ-1208】宠物收养所 Splay

    1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6638  Solved: 2601[Submit][Sta ...

  5. 【BZOJ1208】[HNOI2004]宠物收养所 Splay

    还是模板题,两颗splay,找点删即可. #include <iostream> #include <cstdio> #include <cstdlib> #def ...

  6. BZOJ 1208 宠物收养所

    Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特 ...

  7. BZOJ 1208 宠物收养所 set+二分

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1208 题目大意: 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠 ...

  8. [bzoj1208][HNOI2004]宠物收养所——splay

    题目大意 Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发 ...

  9. HNOI2004宠物收养所(splay维护二叉搜索树模板题)

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

随机推荐

  1. 使用masonry手写约束

    在iOS开发过程中,手写contraints是非常痛苦的一件事情,往往那么一丢丢功能要写大量的代码,非常容易发生错误,并且非常不方便调试.所以只有在不得以的情况下才采用手工方式写contraints, ...

  2. bzoj2004公交线路——DP+矩阵加速递推

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2004 求方案数,想到DP: 因为两个站间距离<=p,所以每p个站中所有车一定都会停靠至 ...

  3. cocos2dx常见32种场景切换动画

    bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init( ...

  4. PostgreSQL 图形化客户端工具有哪些

    linux下有字符界面的:psql         图形界面的:pgaccesswindows系统可以用:phpPgAdmin或者telnet+psql 和phpmyadmin 一家的phpPgAdm ...

  5. 使用JavaScript实现弹出层效果的简单实例

    转自:https://www.jb51.net/article/85475.htm 实现弹出层效果的思路非常简单:将待显示的内容先隐藏,在触发某种条件后(如点击按钮),将原本隐藏的内容显示出来. 实现 ...

  6. ol 与ul 的区别

    1 <!DOCTYPE html> <html> <body> <ul> <li>咖啡</li> <li>牛奶< ...

  7. java中为什么inputstreamreader和buffered reader要配合着用

    因为InputStreamReader是字节输出(汉字会被分为两个字节),而BufferedReader是它的“包装”(整行读取),效率更高,所以配合使用更好.可以通过BufferedReader 流 ...

  8. notepad++的NppFTP插件远程连接linux操作系统

    1.首先要有NppFTP插件,如果没有可以去下面链接或者其他网站下载:  https://sourceforge.net/projects/nppftp/files/latest/download   ...

  9. EJ20170430-hm

    alignment  n. 结盟; 队列,排成直线; 校直,调整; [工] 准线 aspect ratio  n. 宽高比; 纵横比,屏幕高宽比 aspect   n. 方面; thick   n.  ...

  10. python __builtins__ 函数

    dir(__builtins__) 1.'abs', 对传入参数取绝对值 abs(x, /) Return the absolute value of the argument. >>&g ...