宠物收养所

最近,阿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. 收集的java面试题

    1.谈谈final, finally, finalize的区别. final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能既被声明为 ...

  2. spring 笔记3: Spring 多环境配置文件切换

    使用Spring进行开发时,需要面对不同的运行环境,比如开发环境.测试环境.生产环境等.大多时候不同的环境需要不同的配置文件.网上很多资料都是使用Spring的Bean definition prof ...

  3. iframe 如何让它展现内容自适应高度

    引用: <iframe id="ifm1" runat="server" src="/comment/page1?id=@productId&q ...

  4. Android之SQLite总结

    SQLite 是一个轻量级的数据库,常用于各种嵌入式设备当中.android 提供了SQLiteOpenHelper的抽象类用于帮助开发数据库.在实际使用中经常定义一个类继承SQLiteOpenHel ...

  5. CSS 3中细线边框如何实现?

    在app应用开发中,我们常常都需要用到css3来设置应用的样式.由于app都是在移动设备上进行展示,所以边框描边的线一般都小于1px,而以往我们使用的都是1px及以上的.那么问题来了,对于小于1px的 ...

  6. 【转】VS常用快捷键

    每次在网上搜关于VS有哪些常用快捷键的时候,出来的永远是一串长的不能再长的列表,完全没体现出“常用”二字,每次看完前面几个就看不下去了,相信大家都 有这种感觉.其实我们平时用的真的只有很少的一部分,借 ...

  7. IE8专用hack

    众所周知,ie6.7的hack直接用*即可,但是ie8的话就比较麻烦,在做半透明背景的时候,为了兼容ie6.7,可以为其设置纯色,但是ie8也同样不支持半透明,需要单独为它设置纯色背景.下面的兼容代码 ...

  8. [CF999E]Reachability from the Capital

    题目大意:有一个$n$个点$m$条边的有向图,起点$S$,要求你添加最少的边使得$S$可以到达所有点 题解:缩点,答案就是没有入边的强连通分量个数,注意,如果起点$S$所在的强连通块没有入边则不计入答 ...

  9. spring管理事务回滚

    spring 事务回滚 1.遇到的问题 当我们一个方法里面有多个数据库保存操作的时候,中间的数据库操作发生的错误.伪代码如下: ? 1 2 3 4 5 6 7 public method() {    ...

  10. centos 搭建web平台

    centos 查询是否安装apacherpm -qa httpd 出现类似 httpd--.el6.centos..x86_64 ,说明已安装 yum -y install httpd    // 安 ...