宠物收养所

最近,阿Q开了一间宠物收养所。收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物。每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值。这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少。 1. 被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值为a,那么它将会领养一只目前未被领养的宠物中特点值最接近a的一只宠物。(任何两只宠物的特点值都不可能是相同的,任何两个领养者的希望领养宠物的特点值也不可能是一样的)如果有两只满足要求的宠物,即存在两只宠物他们的特点值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物。 2. 收养宠物的人过多,假若到来一只被收养的宠物,那么哪个领养者能够领养它呢?能够领养它的领养者,是那个希望被领养宠物的特点值最接近该宠物特点值的领养者,如果该宠物的特点值为a,存在两个领养者他们希望领养宠物的特点值分别为a-b和a+b,那么特点值为a-b的那个领养者将成功领养该宠物。 一个领养者领养了一个特点值为a的宠物,而它本身希望领养的宠物的特点值为b,那么这个领养者的不满意程度为abs(a-b)。【任务描述】你得到了一年当中,领养者和被收养宠物到来收养所的情况,希望你计算所有收养了宠物的领养者的不满意程度的总和。这一年初始时,收养所里面既没有宠物,也没有领养者。

Input

第一行为一个正整数n,n<=80000,表示一年当中来到收养所的宠物和领养者的总数。接下来的n行,按到来时间的先后顺序描述了一年当中来到收养所的宠物和领养者的情况。每行有两个正整数a, b,其中a=0表示宠物,a=1表示领养者,b表示宠物的特点值或是领养者希望领养宠物的特点值。(同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个)

Output

仅有一个正整数,表示一年当中所有收养了宠物的领养者的不满意程度的总和mod 1000000以后的结果。

Sample Input

5
0 2
0 4
1 3
1 2
1 5

Sample Output

3
(abs(3-2) + abs(2-4)=3,最后一个领养者没有宠物可以领养)

【分析】直接套模板。当宠物剩余,平衡树里存宠物的特点值;当购买者剩余,平衡树里存购买者的喜爱值。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define inf 100000000
#define met(a,b) memset(a,b,sizeof a)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
using namespace std;
const int N =1e6+;
const int M = 4e5+;
struct SBT {
int left,right,size,key;
void Init() {
left=right=;
size=;
}
} tree[N];
int tot,root;
void left_rotate(int &x) { //左旋
int y=tree[x].right;
tree[x].right=tree[y].left;
tree[y].left=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+;
x=y;
}
void right_rotate(int &x) { //右旋
int y=tree[x].left;
tree[x].left=tree[y].right;
tree[y].right=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+;
x=y;
}
void maintain(int &x,int flag) {
if(flag==) {
if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size)
right_rotate(x);
else if(tree[tree[tree[x].left].right].size > tree[tree[x].right].size)
left_rotate(tree[x].left),right_rotate(x);
else return;
} else {
if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size)
left_rotate(x);
else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size)
right_rotate(tree[x].right),left_rotate(x);
else return;
}
maintain(tree[x].left,);
maintain(tree[x].right,);
maintain(x,);
maintain(x,);
}
//插入元素,相同元素放在右子树中
void insert(int &x,int key) {
if(x==) {
x=++tot;
tree[x].Init();
tree[x].key=key;
} else {
tree[x].size++;
if(key<tree[x].key)insert(tree[x].left,key);
else insert(tree[x].right,key);
maintain(x,key>=tree[x].key);
}
}
//删除key值的元素
int del(int &x,int key) {
if(!x)return ;
tree[x].size--;
if(key==tree[x].key || (key<tree[x].key&&tree[x].left==)
|| (key>tree[x].key&&tree[x].right==)) {
if(tree[x].left && tree[x].right) {
int p=del(tree[x].left,key+);
tree[x].key=tree[p].key;
return p;
} else {
int p=x;
x=tree[x].left+tree[x].right;
return p;
}
} else return del(key<tree[x].key?tree[x].left:tree[x].right,key);
}
//**************
//得到前驱,小于
//返回前驱的节点编号
//**************
int get_pre(int &r,int y,int k) {
if(r==)return y;
if(k>tree[r].key)//加个等号就是小于等于
return get_pre(tree[r].right,r,k);
else return get_pre(tree[r].left,y,k);
} //**************
//得到后继,大于
//返回后继的节点编号
//*********
int get_next(int &r,int y,int k) {
if(r==)return y;
if(k<tree[r].key)//加个等号就是大于等于
return get_next(tree[r].left,r,k);
else return get_next(tree[r].right,y,k);
}
//**************
//查找是否存在key值为k的元素
//不存在返回0,存在返回节点编号
//***************
int find(int t,int k) {
while(t && k!=tree[t].key)
t=k<tree[t].key?find(tree[t].left,k):find(tree[t].right,k);
return t;
}
//调试,按顺序输出
void inorder(int &x) {
if(x==)return;
else {
inorder(tree[x].left);
cout<<" "<<tree[x].key<<" "<<tree[x].size<<endl;
inorder(tree[x].right);
}
} //***********
//得到前驱,返回的是小于v的key值,不存在v
//**********
int Pred(int t,int v) {
if(!t)return v;
if(v<=tree[t].key)return Pred(tree[t].left,v);
else {
int tmp=Pred(tree[t].right,v);
return v==tmp?tree[t].key:tmp;
}
}
//***********
//得到后继,返回的是大于v的key值,不存在v
//**********
int Succ(int t,int v) {
if(!t)return v;
if(v>=tree[t].key)return Succ(tree[t].right,v);
else {
int tmp=Succ(tree[t].left,v);
return v==tmp?tree[t].key:tmp;
}
} //得到第k大的元素
int get_Kth(int &x,int k) {
if(k<=tree[tree[x].left].size)
return get_Kth(tree[x].left,k);
if(k>tree[tree[x].left].size+)
return get_Kth(tree[x].right,k-tree[tree[x].left].size-);
return tree[x].key;
} //取最大值
//返回最大值的节点编号
int Get_Max(int x) {
while(tree[x].right)x=tree[x].right;
return x;
}
//取最小值
//返回最小值的节点编号
int Get_Min(int x) {
while(tree[x].left)x=tree[x].left;
return x;
} const int MOD=;
int main() {
int n,a,b;
while(scanf("%d",&n)==) {
root=tot=;//这个初始化一定不要忘记
int flag;
int ans=;
while(n--) {
scanf("%d%d",&a,&b);
if(root==) { //空的
flag=a;
insert(root,b);
} else {
if(a==flag) {
insert(root,b);
} else {
if(find(root,b)) {
del(root,b);
continue;
}
int t1=get_pre(root,,b);
int t2=get_next(root,,b);
if(t1==) {
ans+=abs(tree[t2].key-b);
del(root,tree[t2].key);
ans%=MOD;
} else if(t2==) {
ans+=abs(b-tree[t1].key);
del(root,tree[t1].key);
ans%=MOD;
} else {
if(abs(b-tree[t1].key)<=abs(tree[t2].key-b) ) {
ans+=abs(b-tree[t1].key);
del(root,tree[t1].key);
ans%=MOD;
} else {
ans+=abs(tree[t2].key-b);
del(root,tree[t2].key);
ans%=MOD;
}
}
}
}
}
printf("%d\n",ans);
}
return ;
}

宠物收养所 (SBT)的更多相关文章

  1. Bzoj1208 [HNOI2004]宠物收养所

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 7457  Solved: 2960 Description 最近,阿Q开了一间宠物收养所.收养所提供两 ...

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

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

  3. 宠物收养所(bzoj1208)

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

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

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

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

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

  6. BZOJ1208 宠物收养所

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

  7. C++之路进阶——codevs1285(宠物收养所)

    1285 宠物收养所  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 最近,阿Q开了一间宠物收养所.收养所提供两种服 ...

  8. bzoj 1208: [HNOI2004]宠物收养所 set

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

  9. BZOJ_1208_&_Codevs_1258_[HNOI2004]_宠物收养所_(平衡树/set)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1208 (据说codevs要更新?就不放codevs的地址了吧...) 有宠物和人,每个单位都有 ...

随机推荐

  1. 设计模式之第22章-组合模式(Java实现)

    设计模式之第22章-组合模式(Java实现) “鱼哥,有没有什么模式是用来处理树形的“部分与整体”的层次结构的啊.”“当然”“没有?”“有啊.别急,一会人就到了.” 组合模式之自我介绍 “请问你是?怎 ...

  2. CocosCreator设置模拟器默认横竖屏以及机型

    之前好好的横屏,今天不知道为毛突然变成竖屏了,虽然可以在点击模拟器左上角进行设置,   但是 每次启动模拟器又变成竖屏了,折腾了很久,终于找到了设置的地方,记录下:        

  3. Python全栈 MySQL 数据库(SQL命令大全、MySQL 、Python调用)

    为了梦想与了信仰    开局一张图   主要三个方面: 1.Linux终端命令 2.MySQL语句 3.Python调用   先删库 再跑路.....                         ...

  4. [Ceres]C++优化库

    官网教程: http://ceres-solver.org/nnls_tutorial.html 定义了一个最小二乘法求解器 自动求导的功能

  5. Opencv2.4.13.6安装包

    这个资源是Opencv2.4.13.6安装包,包括Windows软件包,Android软件包,IOS软件包,还有opencv的源代码:需要的下载吧. 点击下载

  6. TensorFlow——深度学习笔记

    深度学习与传统机器学习的区别 传统机器学习输入的特征为人工提取的特征,例如人的身高.体重等,深度学习则不然,它接收的是基础特征,例如图片像素等,通过多层复杂特征提取获得. 深度学习.人工智能.机器学习 ...

  7. C# MemoryCache 类[转载]

    原网址:http://www.cmono.net/post/read/156 MemoryCache 类是.Net .0推出的类库,主要是为了方便在Winform和Wpf中构建缓存框架的 Object ...

  8. 软工实践Alpha冲刺(8/10)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成非功能的主界面制作 ...

  9. linux低权限执行高权限

    1.关于sudo不需要输密码,低权限执行高权限,在root下的命令visudo放开%wheel ALL:保存退出, 执行gpasswd -a yourusername wheel 2.脚本命令下的,权 ...

  10. 高级数据查询SQL语法

    接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL语法, ...