题目链接:http://www.wikioi.com/problem/1285/

算法:Splay

刚开始看到这题,就注意到特征abs了,并且数据n<=80000显然不能暴力,只能用nlgn的做法,综合起来,似乎只有一个答案:Splay。

将每次插入的点splay到树根,然后找到它的前驱和后继,再取它的绝对值即可,我们记作_abs。那么答案就为sum{_absi},其中i为领养的人的数量,可以看为宠物的数量。

要注意的:

  1. 领养者将会领养特点值为a-b的那只宠物 和 特点值为a-b的那个领养者将成功领养该宠物 告诉我们要取前驱。
  2. 同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个。 告诉我们要建两棵Splay树来存剩下的人。
  3. 操作人的和操作动物的几乎一样。

==========================14.06.13==========================

原来写的splay的bug太多,已换成数组= = ps:14.07.26又换成指针。。。。>_<

详细看另一篇splay文章,http://www.cnblogs.com/iwtwiioi/p/3537061.html

=================================很久以前==============================

下面放上代码

#include <cstdio>
using namespace std;
#define F(rt) rt-> pa
#define K(rt) rt-> key
#define CH(rt, d) rt-> ch[d]
#define C(rt, d) (K(rt) > d ? 0 : 1)
#define NEW(d) new Splay(d)
#define PRE(rt) F(rt) = CH(rt, 0) = CH(rt, 1) = null int n, ans, who; struct Splay {
Splay* ch[2], *pa;
int key;
Splay(int d = 0) : key(d) { ch[0] = ch[1] = pa = NULL; }
}; typedef Splay* tree;
tree null = new Splay, root[2] = {null, null}; void rot(tree& rt, int d) {
tree k = CH(rt, d^1), u = F(rt); int flag = CH(u, 1) == rt;
CH(rt, d^1) = CH(k, d); if(CH(k, d) != null) F(CH(k, d)) = rt;
CH(k, d) = rt; F(rt) = k; rt = k; F(rt) = u;
if(u != null) CH(u, flag) = k;
} void splay(tree nod, tree& rt) {
if(nod == null) return;
tree pa = F(rt);
while(F(nod) != pa) {
if(F(nod) == rt)
rot(rt, CH(rt, 0) == nod);
else {
int d = CH(F(F(nod)), 0) == F(nod);
int d2 = CH(F(nod), 0) == nod;
if(d == d2) { rot(F(F(nod)), d); rot(F(nod), d2); }
else { rot(F(nod), d2); rot(F(nod), d); }
}
}
rt = nod;
} tree maxmin(tree rt, int d) {
if(rt == null) return null;
while(CH(rt, d) != null) rt = CH(rt, d);
return rt;
} tree ps(tree rt, int d) {
if(rt == null) return null;
rt = CH(rt, d);
return maxmin(rt, d^1);
} tree search(tree& rt, int d) {
if(rt == null) return null;
tree t = rt;
while(t != null && K(t) != d) t = CH(t, C(t, d));
splay(t, rt);
return t;
} void insert(tree& rt, int d) {
tree q = NULL, t = rt;
while(t != null) q = t, t = CH(t, C(t, d));
t = new Splay(d);
PRE(t);
if(q) F(t) = q, CH(q, C(q, d)) = t;
else rt = t;
splay(t, rt);
} void del(tree& rt) {
if(rt == null) return;
tree t = rt;
if(CH(t, 0) == null) t = CH(rt, 1);
else {
t = CH(rt, 0);
splay(ps(rt, 0), t);
CH(t, 1) = CH(rt, 1);
if(CH(rt, 1) != null) F(CH(rt, 1)) = t;
}
delete rt;
F(t) = null;
rt = t;
} void init(int key, int d) {
if(root[d^1] == null) { who = d; insert(root[who], key); return; }
who = d^1;
insert(root[who], key);
tree succ = ps(root[who], 0), pred = ps(root[who], 1);
int l = 0, r = 0;
if(succ != null) l = K(root[who]) - K(succ);
if(pred != null) r = K(pred) - K(root[who]);
del(root[who]);
if(succ != null && (pred == null || l <= r)) {
ans = (ans + l) % 1000000;
splay(succ, root[who]);
del(root[who]);
}
else if(pred != null && (succ == null || r < l)) {
ans = (ans + r) % 1000000;
splay(pred, root[who]);
del(root[who]);
}
} int main() {
PRE(null);
scanf("%d", &n);
int c, b;
while(~scanf("%d%d", &c, &b)) init(b, c);
printf("%d", ans);
return 0;
}

  

【wikioi】1285 宠物收养所的更多相关文章

  1. splay树 1285 宠物收养所

    #include<cstdio> #include<iostream> using namespace std; int shu[80004][2],n,size,root,k ...

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

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

  3. HNOI2004 宠物收养所 (Treap)

    1285 宠物收养所 http://codevs.cn/problem/1285/  时间限制: 1 s  空间限制: 128000 KB     题目描述 Description 最近,阿Q开了一间 ...

  4. Bzoj1208 [HNOI2004]宠物收养所

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

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

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

  6. 宠物收养所(bzoj1208)

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

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

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

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

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

  9. BZOJ1208 宠物收养所

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

随机推荐

  1. php页面打开响应时间

    $start_time = array_sum(explode(' ',microtime())); //your code here   $end_time = array_sum(explode( ...

  2. 基于网页内容数据采集 PHP开发学习笔记

    jQuery数字的截取: str.toFixed(num);//小数的截取 toFixed() <script type="text/javascript">  var ...

  3. Shell之date用法

    创建以当前时间为文件名的 mkdir `date+%Y%m%d` 备份以时间做为文件名的 tar cvf./htdocs`date +%Y%m%d`.tar ./* date命令如何获得上星期的日期? ...

  4. object-c 继承多态 动态数据类型

    在c#中我们知道有继承的.同样在object-c中也有继承. 例如我们写一个人类(父),一个学生类.我们可以这么写: demo: @interface Person:NSobject{ NSStrin ...

  5. mysql中int、bigint、smallint 和 tinyint的区别与长度的含义

    最近使用mysql数据库的时候遇到了多种数字的类型,主要有int,bigint,smallint和tinyint.其中比较迷惑的是int和smallint的差别.今天就在网上仔细找了找,找到如下内容, ...

  6. lambda 表达式

    C++0x 的语法还是比较简单.下面通过几个例子来介绍下. 先是通过 std::for_each 演示一个简单的例子: ? std::for_each 和 lambda 1 2 3 4 5 6 7 8 ...

  7. BestCoder12 1002.Help him(hdu 5059) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5059 题目意思:就是输入一行不多于 100 的字符串(除了'\n' 和 '\r' 的任意字符),问是否 ...

  8. CodeForces - 404A(模拟题)

    Valera and X Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit ...

  9. 传染病控制(codevs 1091)

    题目描述 Description [问题背景] 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国 大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未 ...

  10. Human Gene Functions(poj 1080)

    题目大意是:给定两组DNA序列,要你求出它们的最大相似度 每个字母与其他字母或自身和空格对应都有一个打分,求在这两个字符串中插入空格,让这两个字符串的匹配分数最大 /* 思路是很好想的,设f[i][j ...