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& ...
随机推荐
- 最详细的github快速入门教程
一:下载github 二:安装GitHub 下载之后点击 进行安装过程,安装之后桌面上会有两个图标,如下图 三:新建项目 GitHub是图形界面模式,Git Shell是命令行模式,在Windows系 ...
- [Python]输出中文报错的解决方法
问题现象:在PyCharm工具编辑python语句输出中文时,程序报错. 解决方法(2种): 1.在代码开头加#coding=utf-8(注意要加#) 2.还是在代码开头加#-*- coding: u ...
- codevs 1390 回文平方数 USACO
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题目描述 Description 回文数是指从左向右念和从右像做念都一样的数.如12321就是一个典型的回文数 ...
- css3 省略号
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; 也无需给元素设置固定宽度!
- wxwidgets编译及环境配置
wxwidgets编译及环境配置 安装步骤: 到www.CodeBlocks.org下载并安装CodeBlocks,最好下载MinGW版本的,可以省掉安装和配置GCC的麻烦. 到www.wxWidge ...
- shell 简单脚本 2
#!/bin/bash source /etc/profile APPLICATIONS_HOME="/cpic/cpicapp/cpic_analy/jars" APPLICAT ...
- Higher level thinking
「Higher level thinking」-- 出自 Ray Dalio 的<Principles>(PDF 原文:Principles by Ray Dalio) Higher le ...
- sql mybatis 使用concat乱码
先贴代码,这是sql查询里面 select id,name,sex,phone,present,adder, CONCAT("从业",experience,"年" ...
- jsTree展开根节点 设置用户图标
$("#jstree").on("loaded.jstree", function (event, data) { var n = 0; var root = ...
- iptables 过滤字符串
iptables 过滤字符串 1. 开启iptables iptables -P OUTPUT ACCEPT ###允许输出链 service iptables save ...