宠物收养所

最近,阿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. cookie不能删除

    cookie不仅仅包含一个键值对,还包含域 domain  路径path, 一般domain是请求的地址 www.baidu.com/news.html 那domain就是www.baidu.com ...

  2. 更改maven本地仓库地址

    1.进入maven安装conf文件中,编辑settings.xml文件,新增图中的圈出的内容(我想要存放的地址是D:\HMY\m2\repository) 2.复制settings.xml文件至D:\ ...

  3. jsonp、瀑布流布局、组合搜索、多级评论(评论树)、Tornado初识

    1.JSONP原理剖析以及实现 1.1 同源策略限制 用django分别建立两个项目,jsonp01和jsonp02,然后再在这两个项目里分别建立一个app,比如名字叫jsonp1.jsonp2:js ...

  4. 爬虫:Scrapy13 - 发送 email

    虽然 Python 通过 smtplib 库使得发送 email 变得非常简单,Scrapy 仍然提供了自己的实现.该功能十分易用,同时由于采用了 Twisted 非阻塞式(non-blocking) ...

  5. bpf 指令集

    58 struct bpf_insn { 59 __u8 code; /* opcode */ 60 __u8 dst_reg:4; /* dest register */ 61 __u8 src_r ...

  6. LeetCode -- Search a 2D Matrix & Search a 2D Matrix II

    Question: Search a 2D Matrix Write an efficient algorithm that searches for a value in an m x n matr ...

  7. babelrc配置

    { "presets": [ ["env", { // webapck2/3必须配置,放弃使用babel的模块化,使用webpack的模块化,webpack1不 ...

  8. python列表里的字典元素去重

    去重 def list_dict_duplicate_removal(): data_list = [{"a": "123", "b": & ...

  9. pagination用法

    pagination用法: 1.html  要用两层div <script src="${app }/pc/js/media/pagination.js"></s ...

  10. BZOJ 1492 [NOI2007] - cash

    Description 最初你有 S 块钱, 有 N 天给你来兑换货币, 求最大获利. 一共只有两种货币 A , B . 对于每一天, 给定 3 个系数 A[i], B[i], Rate[i] A[i ...