BZOJ 1208 [HNOI2004]宠物收养所:Splay(伸展树)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1208
题意:
有一个宠物收养所,在接下来一段时间内会陆续有一些宠物进到店里,或是一些人来领养宠物。宠物和人的总数量为n。
t = 0代表宠物,t = 1代表人。
宠物和人分别有一个特点值a和b。有两种情况:
(1)店里全是宠物,这时进来一个人来领养宠物。那么他会领养走abs(a-b)最小的那只宠物(b = a - x or a + x)。
如果使得abs(a-b)最小的有不止一只宠物,那么b = a - x的那只会被领养走。
(2)店里全是等待的人。这事有一只宠物被送进店里,那么它会被abs(a-b)最小的那个人领养走(a = b - x or b + x)。
如果使得abs(a-b)最小的不只有一个人,那么宠物会被a = b - x的人领养走。
按照依次来到店里的顺序,给出a,b。
a = 0代表宠物,a = 1代表人。b为对应的特点值。
定义每一次领养的不满意度 = abs(宠物特点值 - 人的特点值)
问你所有不满意度之和 MOD 1000000。
题解:
Splay。
分析:
(1)在每一个时刻(除了正在领养),店里要么全是宠物,要么全是人,要么为空。
(2)在本题中,除了只能是人和宠物匹配这个特性,人和宠物是等价的,都可以在店里等待。
(3)有可能先进来一大堆宠物,再进来一大堆人。这时搜索树会退化成链,所以要用splay。
实现:
每输入一对a,b:
(1)如果店为空,那么将东西加入树中,并将树的类型改为a。
(2)如果进来一个同类,那么将当前东西加入树中。
(3)如果进来一个异类,那么找出对于这个异类的特点值的前驱pre与后继suc(类型均为pair<int,int>(dif,idx))。
将被删除的东西为res = min(pre,suc)。
所以erase(res.second),并更新答案ans = (ans + res.first) % MOD。
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 80005
#define MOD 1000000
#define INF 100000000 using namespace std; int n,a,b;
int ans=;
int type;
int siz=;
int tot=;
int root=-;
int dat[MAX_N];
int par[MAX_N];
int lson[MAX_N];
int rson[MAX_N]; void rotate(int x,int type,int *lson,int *rson)
{
if(type==) swap(lson,rson);
int y=par[x];
int z=par[y];
lson[y]=rson[x];
if(rson[x]!=-) par[rson[x]]=y;
par[x]=z;
if(z!=-)
{
if(lson[z]==y) lson[z]=x;
else rson[z]=x;
}
rson[x]=y;
par[y]=x;
} void splay(int x,int act)
{
while(par[x]!=act)
{
int y=par[x];
int z=par[y];
if(z==act)
{
if(lson[y]==x) rotate(x,,lson,rson);
else rotate(x,,lson,rson);
}
else
{
if(lson[z]==y && lson[y]==x)
{
rotate(y,,lson,rson);
rotate(x,,lson,rson);
}
if(rson[z]==y && rson[y]==x)
{
rotate(y,,lson,rson);
rotate(x,,lson,rson);
}
if(rson[z]==y && lson[y]==x)
{
rotate(x,,lson,rson);
rotate(x,,lson,rson);
}
if(lson[z]==y && rson[y]==x)
{
rotate(x,,lson,rson);
rotate(x,,lson,rson);
}
}
}
if(act==-) root=x;
} int find(int val)
{
int now=root;
while(now!=-)
{
if(val==dat[now]) return now;
if(val<dat[now]) now=lson[now];
if(val>dat[now]) now=rson[now];
}
return -;
} void new_node(int val,int p,int &kid)
{
dat[tot]=val;
par[tot]=p;
lson[tot]=-;
rson[tot]=-;
kid=tot;
splay(tot,-);
tot++;
} void insert(int val)
{
siz++;
if(root==-)
{
int temp;
root=tot;
new_node(val,-,temp);
return;
}
int now=root;
while()
{
if(val==dat[now]) return;
if(val<dat[now])
{
if(lson[now]==-)
{
new_node(val,now,lson[now]);
return;
}
else now=lson[now];
}
if(val>dat[now])
{
if(rson[now]==-)
{
new_node(val,now,rson[now]);
return;
}
else now=rson[now];
}
}
} void erase(int x)
{
siz--;
splay(x,-);
if(lson[x]==- && rson[x]==-)
{
root=-;
return;
}
if(lson[x]==-)
{
root=rson[x];
par[rson[x]]=-;
return;
}
if(rson[x]==-)
{
root=lson[x];
par[lson[x]]=-;
return;
}
int pre=lson[root];
while(rson[pre]!=-) pre=rson[pre];
splay(pre,x);
par[pre]=-;
rson[pre]=rson[x];
par[rson[x]]=pre;
root=pre;
} pair<int,int> precursor(int val)
{
int now=root;
int pre=-;
int dif=INF;
while(now!=-)
{
if(dat[now]<val && val-dat[now]<dif)
{
pre=now;
dif=val-dat[now];
}
if(dat[now]>val) now=lson[now];
else now=rson[now];
}
return pair<int,int>(dif,pre);
} pair<int,int> succeed(int val)
{
int now=root;
int suc=-;
int dif=INF;
while(now!=-)
{
if(dat[now]>val && dat[now]-val<dif)
{
suc=now;
dif=dat[now]-val;
}
if(dat[now]>val) now=lson[now];
else now=rson[now];
}
return pair<int,int>(dif,suc);
} int main()
{
cin>>n;
for(int i=;i<n;i++)
{
cin>>a>>b;
if(siz==)
{
insert(b);
type=a;
}
else
{
if(a==type) insert(b);
else
{
pair<int,int> pre=precursor(b);
pair<int,int> suc=succeed(b);
pair<int,int> res=min(pre,suc);
erase(res.second);
ans=(ans+res.first)%MOD;
}
}
}
cout<<ans<<endl;
}
BZOJ 1208 [HNOI2004]宠物收养所:Splay(伸展树)的更多相关文章
- Bzoj 1208: [HNOI2004]宠物收养所(splay)
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MB Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收 ...
- BZOJ 1208 [HNOI2004]宠物收养所 | SPlay模板题
题目: 洛谷也能评 题解: 记录一下当前树维护是宠物还是人,用Splay维护插入和删除. 对于任何一次询问操作都求一下value的前驱和后继(这里前驱和后继是可以和value相等的),比较哪个差值绝对 ...
- BZOJ 1208: [HNOI2004]宠物收养所
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7514 Solved: 2982[Submit][Sta ...
- BZOJ 1208: [HNOI2004]宠物收养所(BST)
本来想先用set写一遍,再自己写个splay或treap,不过用set过了之后就懒得去写了....以后有空再来写吧..(不会有空的吧= = ------------------------------ ...
- BZOJ 1208: [HNOI2004]宠物收养所 SET的妙用
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4902 Solved: 1879 题目连接 http:/ ...
- bzoj 1208: [HNOI2004]宠物收养所 set
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7328 Solved: 2892[Submit][Sta ...
- bzoj 1208: [HNOI2004]宠物收养所 (Treap)
链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1208 题面: 1208: [HNOI2004]宠物收养所 Time Limit: 10 ...
- bzoj 1208 HNOI2004宠物收养所 平衡树
裸平衡树,恢复手感用的 //By BLADEVIL var n :longint; i :longint; x, y :longint; t, tot :longint; key, s, left, ...
- 1208: [HNOI2004]宠物收养所
1208: [HNOI2004]宠物收养所 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 12030 Solved: 4916 Description ...
随机推荐
- java8新特性学习笔记(二) 流的相关思想
流是什么 流是Java API的新成员,他允许你以声明的方式处理数据集合,就现在来说,可以把他们看成遍历数据集合的高级迭代器.此外,流还可以透明地并行处理,你无须写任何多线程代码. 下面例子是新老AP ...
- 请求php文件的整个流程
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- redis远程登录
#redis-cli -h 202.96.126.37 -p 6379 #auth 'd6d72fa9b2ff458e:GRjZmQ3MTN'
- Linux XMind
XMind这个软件好像不错的样子,至少在Windows/Linux/Mac下都可以工作,作为FreeMind的替代品应该是没什么问题(还有一个vym貌似也可以,可能没有XMind好,毕竟XMind有公 ...
- 机器学习实战之K-Means算法
一,引言 先说个K-means算法很高大上的用处,来开始新的算法学习.我们都知道每一届的美国总统大选,那叫一个竞争激烈.可以说,谁拿到了各个州尽可能多的选票,谁选举获胜的几率就会非常大.有人会说,这跟 ...
- php解码“&#”编码的中文用函数html_entity_decode()
遇到类似 ' 这种编码的字,我们可以用html_entity_decode()函数来解码. html_entity_decode() 函数把 HTML 实体转换为字符. 语法 html_entity_ ...
- JAVA进阶-多线程(2)
堵塞队列: 1)BlockingQueue该接口提供了: add()/remove() 假设当队列没有数据,从队列中取数据;或者队列中数据已满, 向队列中加入数据;则会抛出异常. put()/take ...
- 1-1:CSS3课程入门之属性选择器
div[name=jewave] 选取属性名为name且属性值是"jewave"的元素 div[name^=jewave]选取属性名为name且属性值以"jewave&q ...
- 查看并修改Linux主机名命令hostname
查看主机名 hostname可以查看主机名 export也可以查看 修改主机名 echo new-hostname > /proc/sys/kernel/hostname (系统启动时,从此文件 ...
- 局部描述符表LDT的作用+定义+初始化+跳转相关
[0]写在前面 0.1)本代码的作用: 旨在说明局部描述符表的作用,及其相关定义,初始化和跳转等内容: 0.2)文末的个人总结是干货,前面代码仅供参考的,且source code from orang ...