POJ-1442 Black Box,treap名次树!
唉,一天几乎就只做了这道题,成就感颇低啊!
题意:有一系列插入查找操作,插入每次在有序数列中插入一个数,保证插入后数列还是有序,初始数列为空,每次查询一个排名为i的数,第i次查询排名为i的数。给你两个数列,第一个是插入数的顺序,第二个是每次查询发生在插入第U(i)个数之后。具体看样例,说实话我也理解了挺久,数列1 2 6 6 表示的是第一次查询是在插入第一个数之后,第二次查询是在插入第二个数之后,第三次第四次查询都是在插入第六个数之后,但第三第四次查询的排名就不同了。
思路:可惜set无法用下标访问啊,所以treap有着set无法比拟的优势。这题除了treap当然也还有其他的方法了。用treap是比较简单了,不涉及删除操作,只有查找插入和旋转三种,唯一不同的就是每个节点加了一个size域用来表示左右子树和本身的节点数之和。这样每次查询排名为k的也就是第k小的数,只需判断节点左子树的节点个数的关系然后选择在左子树还是右子树中查找。
int a[N],b[N];
struct node
{
node *ch[2];
int r,v,s;
node(int vv)
{
r=rand();//优先级
v=vv;//值
ch[0]=ch[1]=NULL;
}
void maintain()
{
s=1;//左右子树的节点数加一(本身一个节点)
if(ch[0]) s+=ch[0]->s;
if(ch[1]) s+=ch[1]->s;
}
};
int find(node *root,int s)//查找排名为s的节点值,即第s小
{
int k=root->ch[0]==NULL?0:root->ch[0]->s;
if(s==k+1) return root->v;
else if(s<=k) return find(root->ch[0],s);
return find(root->ch[1],s-k-1);
}
void rotate(node *&root,int d)//d为0代表左旋
{
node *tmp=root->ch[d^1];
root->ch[d^1]=tmp->ch[d];
tmp->ch[d]=root;
root->maintain();//注意先维护root,再维护tmp,因为之后tmp节点就相当于是root了,最后还是要赋给root的
tmp->maintain();
root=tmp;
}
void insert(node *&root,int v)
{
if(root==NULL) root=new node(v);
else
{
int d=v<root->v?0:1;//左子树都比根节点小,右子树都比根节点大
insert(root->ch[d],v);
if(root->ch[d]->r > root->r) rotate(root,d^1);
}
root->maintain();
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
node *root=NULL;
int j=1;
for(int i=1;i<=n;i++)
{
insert(root,a[i]);
while(j<=m&&b[j]<=i)
{
int v=find(root,j);
printf("%d\n",v);
j++;
}
}
}
return 0;
}
人生第二道treap题,我好菜啊~~
POJ-1442 Black Box,treap名次树!的更多相关文章
- POJ 1442 Black Box treap求区间第k大
题目来源:POJ 1442 Black Box 题意:输入xi 输出前xi个数的第i大的数 思路:试了下自己的treap模版 #include <cstdio> #include < ...
- poj 1442 Black Box(优先队列&Treap)
题目链接:http://poj.org/problem?id=1442 思路分析: <1>维护一个最小堆与最大堆,最大堆中存储最小的K个数,其余存储在最小堆中; <2>使用Tr ...
- 「模板」「讲解」Treap名次树
Treap实现名次树 前言 学平衡树的过程可以说是相当艰难.浏览Blog的过程中看到大量指针版平衡树,不擅长指针操作的我已经接近崩溃.于是,我想着一定要写一篇非指针实现的Treap的Blog. 具体如 ...
- UVa 1479 (Treap 名次树) Graph and Queries
这题写起来真累.. 名次树就是多了一个附加信息记录以该节点为根的树的总结点的个数,由于BST的性质再根据这个附加信息,我们可以很容易找到这棵树中第k大的值是多少. 所以在这道题中用一棵名次树来维护一个 ...
- POJ 1442 Black Box(优先队列)
题目地址:POJ 1442 这题是用了两个优先队列,当中一个是较大优先.还有一个是较小优先. 让较大优先的队列保持k个.每次输出较大优先队列的队头. 每次取出一个数之后,都要先进行推断,假设这个数比較 ...
- LA 5031 Graph and Queries —— Treap名次树
离线做法,逆序执行操作,那么原本的删除边的操作变为加入边的操作,用名次树维护每一个连通分量的名次,加边操作即是连通分量合并操作,每次将结点数小的子树向结点数大的子树合并,那么单次合并复杂度O(n1lo ...
- POJ 1442 Black Box
第k大数维护,我推荐Treap..谁用谁知道.... Black Box Time ...
- poj 1442 Black Box(堆 优先队列)
题目:http://poj.org/problem?id=1442 题意:n,m,分别是a数组,u数组的个数,u[i]w为几,就加到a几,然后输出第i 小的 刚开始用了一个小顶堆,超时,后来看了看别人 ...
- POJ 1442 Black Box 堆
题目: http://poj.org/problem?id=1442 开始用二叉排序树写的,TLE了,改成优先队列,过了.. 两个版本都贴一下吧,赚稿费.. #include <stdio.h& ...
随机推荐
- 2017“编程之美”终章:AI之战勇者为王
编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...
- 洛谷 P2984 [USACO10FEB]给巧克力Chocolate Giving
题目描述 Farmer John is distributing chocolates at the barn for Valentine's day, and B (1 <= B <= ...
- windows定时任务小注
static class Program { /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static vo ...
- 图片,二进制,oracle数据库
图片在oracle数据库中一般以二进制存在,存储类型是blob,然而clob类型一般存储的是大于4000的字符,不能用来存储图像这样的二进制内容,下面展示一下实现图像,二进制,oracle 数据库的应 ...
- android 焦点 ListView 点击事件获取失败
1. 在ListView 中, 创建一个app_item.xml 布局文件 在布局文件中有如下的代码: <CheckBox android:id="@+id/cb_t ...
- Spring中的事务传播行为与隔离级别
事务传播行为 事务传播行为(为了解决业务层方法之间互相调用的事务问题): 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己 ...
- WPF中单选框RadioButton
单选框RadioButton的基本使用: <StackPanel Margin="10"> <Label FontWeight="Bold"& ...
- JavaScript中valueOf函数与toString方法
基本上,所有JS数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下 JavaScrip ...
- python常用模块之json和pickle模块
json模块 json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 用于解码 JSON 数据.该函数返回 Python 字段的数据类型. pi ...
- 【转】IntelliJ 创建main函数快捷
http://blog.csdn.net/tiantiandjava/article/details/42269173 今天偶然发现了IntelliJ中 创建main函数的快捷键,依次还有for循环, ...