洛谷 P2286 [HNOI2004]宠物收养场
题目描述
凡凡开了一间宠物收养场。收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物。
每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养场的宠物一个特点值。这样他就能够很方便的处理整个领养宠物的过程了,宠物收养场总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少。
被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值为a,那么它将会领养一只目前未被领养的宠物中特点值最接近a的一只宠物。(任何两只宠物的特点值都不可能是相同的,任何两个领养者的希望领养宠物的特点值也不可能是一样的)如果有两只满足要求的宠物,即存在两只宠物他们的特点值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物。
收养宠物的人过多,假若到来一只被收养的宠物,那么哪个领养者能够领养它呢?能够领养它的领养者,是那个希望被领养宠物的特点值最接近该宠物特点值的领养者,如果该宠物的特点值为a,存在两个领养者他们希望领养宠物的特点值分别为a-b和a+b,那么特点值为a-b的那个领养者将成功领养该宠物。
一个领养者领养了一个特点值为a的宠物,而它本身希望领养的宠物的特点值为b,那么这个领养者的不满意程度为abs(a-b)。
你得到了一年当中,领养者和被收养宠物到来收养所的情况,请你计算所有收养了宠物的领养者的不满意程度的总和。这一年初始时,收养所里面既没有宠物,也没有领养者。
输入输出格式
输入格式:
第一行为一个正整数n,n<=80000,表示一年当中来到收养场的宠物和领养者的总数。接下来的n行,按到来时间的先后顺序描述了一年当中来到收养场的宠物和领养者的情况。每行有两个正整数a, b,其中a=0表示宠物,a=1表示领养者,b表示宠物的特点值或是领养者希望领养宠物的特点值。(同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个)
输出格式:
仅有一个正整数,表示一年当中所有收养了宠物的领养者的不满意程度的总和mod 1000000以后的结果。
输入输出样例
输入样例#1:
5
0 2
0 4
1 3
1 2
1 5
输出样例#1:
3
注:abs(3-2) + abs(2-4)=3,
最后一个领养者没有宠物可以领养。
思路:思路呢其实就是对于每种情况找给出b的前驱和后继的值,而找前驱和后继,最好办法就是平衡树,然而平衡树我最熟悉的是splay,于是就写了splay,这道题因为每个宠物的特点值不同,每个领养者需要的特点值也都不相同,因此,不需要维护每个结点的cnt(出现的次数),节省了代码量。
代码:
#include<cstdio>
#include<cctype>
#include<algorithm>
#define maxn 80007
#define mod 1000000
#define ll long long
using namespace std;
int root,tot,n,cnt;
ll ans;
inline int qread() {
char c=getchar();int num=0,f=1;
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) num=num*10+c-'0';
return num*f;
}
struct Tree {
int fa,ch[2];
ll val;
}t[maxn];
inline void rotate(int x) {
int y=t[x].fa,z=t[y].fa;
int k=t[y].ch[1]==x;
t[z].ch[t[z].ch[1]==y]=x;
t[x].fa=z;
t[y].ch[k]=t[x].ch[k^1];
t[t[x].ch[k^1]].fa=y;
t[x].ch[k^1]=y,t[y].fa=x;
}
inline void splay(int x, int rt) {
while(t[x].fa!=rt) {
int y=t[x].fa,z=t[y].fa;
if(z!=rt) (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
if(!rt) root=x;
}
inline void insert(int x) {
int u=root,f=0;
while(u&&t[u].val!=x) {
f=u;
u=t[u].ch[x>t[u].val];
}
if(u);
else {
u=++tot;
if(f) t[f].ch[x>t[f].val]=u;
t[u].fa=f,t[u].val=x;
}
splay(u,0);
}
inline void find(int x) {
int u=root;
if(!u) return;
while(t[u].ch[x>t[u].val]&&x!=t[u].val) u=t[u].ch[x>t[u].val];
splay(u,0);
}
inline int nxt(int x, int f) {
find(x);
int u=root;
if(t[u].val>x&&f) return u;
if(t[u].val<x&&!f) return u;
u=t[u].ch[f];
while(t[u].ch[f^1]) u=t[u].ch[f^1];
return u;
}
inline int nx(int x, int f) {
find(x);
int u=root;
if(t[u].val>=x&&f) return u;
if(t[u].val<=x&&!f) return u;
u=t[u].ch[f];
while(t[u].ch[f^1]) u=t[u].ch[f^1];
return u;
}
inline void sc(int x) {
int last=nxt(x,0),next=nxt(x,1);
splay(last,0),splay(next,last);
t[next].ch[0]=0;
}
int main() {
n=qread();
insert(0x3f3f3f3f),insert(-0x3f3f3f3f);
for(int i=1,x,y;i<=n;++i) {
x=qread(),y=qread();
if(!cnt) insert(y);
if(cnt<0) {
if(!x) insert(y);
else {
int pre=t[nx(y,0)].val,zrj=t[nx(y,1)].val;
if(abs(y-pre)<=abs(y-zrj)) {
ans+=abs(y-pre)%mod;
sc(pre);
}
else {
ans+=abs(y-zrj)%mod;
sc(zrj);
}
}
}
if(cnt>0) {
if(x) insert(y);
else {
int pre=t[nx(y,0)].val,zrj=t[nx(y,1)].val;
if(abs(y-pre)<=abs(y-zrj)) {
ans+=abs(y-pre)%mod;
sc(pre);
}
else {
ans+=abs(y-zrj)%mod;
sc(zrj);
}
}
}
cnt+=(x==0?-1:1);
}
printf("%lld\n",ans%mod);
return 0;
}
洛谷 P2286 [HNOI2004]宠物收养场的更多相关文章
- 洛谷P2286 [HNOI2004]宠物收养场【Treap】题解+AC代码
题目传送门啦~啦~啦~ 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的 ...
- 洛谷P2286 [HNOI2004]宠物收养场
题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
- 洛谷P2286 [HNOI2004]宠物收养所 [STL,平衡树]
题目传送门 宠物收养所 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的 ...
- 洛谷:P3384 [HNOI2004]宠物收养场
原题地址:https://www.luogu.org/problemnew/show/P3384 题目简述 给定一些序列(没有重复数字),每个序列支持: 给定一些数k(对于每个序列不重复),每次在序列 ...
- P2286 [HNOI2004]宠物收养场
题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
- 洛谷$P$2286 宠物收养场 $[HNOI2004]$ $splay$
正解:$splay$ 解题报告: 传送门! $splay$板子,,,? 先考虑这题要实现些什么东西嘛$QwQ$ 其实只要实现一个东西?就查询数列中与给定数字相差最小的数,显然用$splay$查询前驱后 ...
- Luogu P2286 [HNOI2004]宠物收养场
一道比较简单的直接Treap运用题目,思维难度和代码难度都不是很高. 题意有点长,我们仔细剖析一下题意发现以下几个关键: 任何时候收养站里只可能有人和宠物中的其中一种,或者都没有 如果只有宠物并有人来 ...
- [HNOI2004]宠物收养场 Treap前驱后继
凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领 ...
- BZOJ1208[HNOI2004]宠物收养场——treap
凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领 ...
随机推荐
- 关于FPGA设计16位乘法器的两…
原文地址:关于FPGA设计16位乘法器的两种算法作者:ChrisChan 部分原代码如下: 用特权的右移算法虽复杂点,但节省不少LEs,如下图: 用左移算法尽管浅显易懂,但因每次都会从最右端移位,会占 ...
- 【COCI2012】覆盖字符串
[题目描述] 给出一个长度为N的小写字母串,现在Mirko有M个若干长度为Li字符串.现在Mirko要用这M个字符串去覆盖给出的那个字符串的.覆盖时,必须保证:1.Mirko的字符串不能拆开,旋转:2 ...
- Python编写两个数的加减法游戏
目标: 1.实现两个数的加减法 2.回答者3次输错计算结果后,输出正确结果,并询问回答者是否继续 1.使用常规函数实现两个数的加减法游戏 代码如下: #!/usr/bin/env python # - ...
- Flask框架 之 路由和视图详解
路由+视图 我们之前了解了路由系统是由带参数的装饰器完成的. 路由本质:装饰器和闭包实现的. 路由设置的两种方式 来看个例子. @app.route('/index') def index(): re ...
- jquery表单数据反序列化为字典
.前台代码 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1 ...
- Reading Text-based Files In ASP.NET
Friday, July 17, 2015 1:43 PM Every time I need to work with the contents of text-based files in an ...
- 打造一套UI与后台并重.net通用权限管理系统
一.前言 从进行到软件开发这个行业现在已经有几年了,在整理出这个套开发框架之前自己做了不少重复造轮子的事.每次有新的项目总是要耗费不少时间在UI.权限和系统通用模块上面,自己累得要死,老板还骂没效率. ...
- 代理(Proxy)模式
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的反问. * 抽象主题角色(Subject):声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题. * ...
- 装饰(Decorator)模式
一. 装饰(Decorator)模式 装饰(Decorator)模式又名包装(Wrapper)模式[GOF95].装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 二. 装饰模式 ...
- sqlTransaction 简单的应用
sqlTansaction表示要在 SQL Server 数据库中处理的 Transact-SQL 事务 static void Main(strng[] args) { //往数据库里面插入数据 s ...