hihocoder-平衡树·SBT
http://hihocoder.com/problemset/problem/1337
#1337 : 平衡树·SBT
描述
小Ho:小Hi,之前你不是讲过Splay和Treap么,那么还有没有更简单的平衡树呢?
小Hi:但是Splay和Treap不是已经很简单了么?
小Ho:是这样没错啦,但是Splay和Treap和原来的二叉搜索树相比都有很大的改动,我有点记不住。
小Hi:这样啊,那我不妨再给你讲解一个新的平衡树算法好了。和二叉搜索树相比,它只需要修改insert函数,就可以做到高度的平衡。
小Ho:好,我就喜欢这样的!
输入
第1行:1个正整数n,表示操作数量,10≤n≤100,000
第2..n+1行:每行1个字母c和1个整数k:
若c为'I',表示插入一个数字k到树中,-1,000,000,000≤k≤1,000,000,000
若c为'Q',表示询问树中第k小数字,保证1≤k≤树的节点数量
输出
若干行:每行1个整数,表示针对询问的回答,保证一定有合法的解
- 样例输入
-
5
I 3
I 2
Q 1
I 5
Q 2 - 样例输出
-
2
3
---恢复内容结束---
动态查询Ktop系列
1.对于固定的Ktop系列,可以使用 优先队列,最小堆,Treap,BST,SBT
2.动态的Ktop Treap,BST,SBT 效率: BST<Treap<SBT
解法一 使用二叉搜索树: 此方法是直接建立起二叉树,对于树不做调整,这会造成树变得很长!
遇到的坑: Java swap不能像C++那样,C++可以传地址,传值,传应用但是Java并不是,Java只能传值,并且传递参数的时候,使用的是深copy,也就是参数的对象和本尊不是同一个对象地址,而仅仅是和它拥有相同数值的不同对象。所以swap不能像C++那样.

import java.util.Scanner; /**
* author: 龚细军
* class-aim:
*/ class Node {
public Integer key;
public long size;
public Node left;
public Node right; public Node() {
size = 0;
key = null;
left = right = null;
}
} /*二叉排序树,此题不需要调解平衡*/
class BSTree {
private static final int DEFAULT_INITIAL_CAPACITY = 1; public static int query(Node node, int kMin) {
Long flag = node.left.size - kMin + 1;
if (flag == 0) return node.key;
if (flag < 0) return query(node.right, (int) abs(flag));
return query(node.left, kMin);
} private static long abs(Long flag) {
return flag > 0 ? flag : -1 * flag;
} public static void insert(Node node, int data) {
if (node.size > 0) {
node.size++;
insert(data > node.key ? node.right : node.left, data);
} else {
node.key = data;
node.size = DEFAULT_INITIAL_CAPACITY;
node.left = new Node();
node.right = new Node();
}
} } public class Main { public static void main(String args[]) {
int num, val;
String cmd;
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
num = scanner.nextInt();
Node root = new Node();
while (num-- > 0) {
cmd = scanner.next();
val = scanner.nextInt();
if (cmd.equals("I")) BSTree.insert(root, val);
else {
System.out.println(BSTree.query(root, val));
}
}
}
} }
解法二: SBT树 平衡树,在解法一基础上进行优化,也就每次对其不满足这样条件的进行调整:
node.left.size >= max(node.right.right.size,node.right.left.size);
node.right.size >= max(node.left.right.size , node.left.left.size);
进行平衡调整.这样就可以使其查询数据降到O(lgn)


import java.util.Scanner; /**
* author: 龚细军
* class-aim:
*/ class Node {
public int key, size;
public Node left, right; public Node() {
this.size = 0;
this.left = null;
this.right = null;
} public void clone(Node node) {
this.key = node.key;
this.size = node.size;
this.left = node.left;
this.right = node.right;
}
} public class Main {
private static final int DEFAULT_INITIAL_CAPACITY = 1; public static int getSize(Node node) {
return node == null ? 0 : node.size;
} public static int compare(Node a, int key) {
return a.key - key;
} public static void update(Node node) {
if (node == null) return;
node.size = getSize(node.left) + getSize(node.right) + 1;
} public static void rightRotate(Node master, Node node) {
Node newNode = new Node();
newNode.clone(master);
newNode.left = node.right;
node.right = newNode;
update(newNode);
update(node);
master.clone(node);
} public static void leftRotate(Node master, Node node) {
Node tmpNode = new Node();
tmpNode.clone(master);
tmpNode.right = node.left;
node.left = tmpNode;
update(tmpNode);
update(node);
master.clone(node);
} public static void insert(Node master, int key) { if (master.size == 0) {
master.left = new Node();
master.right = new Node();
master.size = DEFAULT_INITIAL_CAPACITY;
master.key = key;
} else if (compare(master, key) > 0) {
insert(master.left, key);
if (getSize(master.left.left) > getSize(master.right)) {
//右旋转
rightRotate(master, master.left);
}
} else {
insert(master.right, key);
if (getSize(master.right.right) > getSize(master.left)) {
//左旋转
leftRotate(master, master.right);
}
} update(master); } private static int abs(int flag) {
return flag > 0 ? flag : -1 * flag;
} public static int query(Node node, int kMin) { int flag = node.left.size - kMin + 1;
if (flag == 0) return node.key;
if (flag < 0) return query(node.right, abs(flag));
return query(node.left, kMin);
} public static void main(String args[]) {
int num, val;
String cmd;
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
num = scanner.nextInt();
Node root = new Node();
while (num-- > 0) {
cmd = scanner.next();
val = scanner.nextInt();
if (cmd.equals("I"))
Main.insert(root, val);
else
System.out.println(Main.query(root, val));
}
}
}
}
hihocoder-平衡树·SBT的更多相关文章
- tyvj 普通平衡树 SBT or splay
普通平衡树 From admin 背景 Background 此为平衡树系列第一道:普通平衡树 描述 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中 ...
- 【bzoj3435】[Wc2014]紫荆花之恋 替罪点分树套SBT
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
- Hihocoder 1337 (splay)
Problem 平衡树 SBT 题目大意 维护一个序列,支持两种操作. 操作一:插入一个数. 操作二:询问第k小的数. 解题分析 ~~刷刷水题,再熟悉一下splay的基本操作. ps:哇咔咔,有连续四 ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 子树大小平衡树(Size Balanced Tree,SBT)操作模板及杂谈
基础知识(包括但不限于:二叉查找树是啥,SBT又是啥反正又不能吃,平衡树怎么旋转,等等)在这里就不(lan)予(de)赘(duo)述(xie)了. 先贴代码(数组模拟): int seed; int ...
- HDU 4006 The kth great number 优先队列、平衡树模板题(SBT)
The kth great number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Oth ...
- 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】
平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是 ...
- Hihocoder 1325 平衡树·Treap(平衡树,Treap)
Hihocoder 1325 平衡树·Treap(平衡树,Treap) Description 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉 ...
- HihoCoder 1325 平衡树·Treap
HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...
随机推荐
- iOS检测用户截屏并获取所截图片
iOS检测用户截屏并获取所截图片 微信可以检测到用户截屏行为(Home + Power),并在稍后点击附加功能按钮时询问用户是否要发送刚才截屏的图片,这个用户体验非常好.在iOS7之前, 如果用户截屏 ...
- Hello Spring Framework——面向切面编程(AOP)
本文主要参考了Spring官方文档第10章以及第11章和第40章的部分内容.如果要我总结Spring AOP的作用,不妨借鉴文档里的一段话:One of the key components of S ...
- web项目 log4j2的路径问题
项目中用到log4j2记录日志,结果运行的时候总也不见log文件的产生. 查看官方文档得知,在web项目中使用log4j2需要加入log4j-web包 log4j2.xml <?xml vers ...
- sql 查询表中所有字段的名称
最近工作用到SQL语句查询表中所有字段的名称,网上查询,发现不同数据库的查询方法不同,例如: SQL server 查询表的所有字段名称:Select name from syscolumns Whe ...
- Linux Shell基础知识
一.文件系统和安全 chmod命令 chmod命令有两种模式,一种是符号模式,用ugo执行用户,用rwx执行权限:另一种是绝对模式,用八进制不同位置的不同值来代表不同用户的不同权限. 符号模式 chm ...
- Network网络
ifconfig 查看服务器网卡名称 ethtool ethXXX 查看网卡具体信息 要测试一个网卡是否真是1000M的,最保险的说用wget测试一个对方的带宽足够大的下载地址 wget http:/ ...
- ORACLE 11g安装
下载地址 win 32位操作系统 下载地址: http://download.oracle.com/otn/nt/oracle11g/112010/win32_11gR2_database_1of2. ...
- 【Treap】bzoj1588-HNOI2002营业额统计
一.题目 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司 ...
- Git 笔记整理3
1,git clone某一个分支 git clone -b <branch> <remote_repo> 2,.git 文件太大 :clone的时候,可以指定深度,如下,为1即 ...
- 通过js给android控件WebView设padding
项目中有个界面是用来显示一个网页的,很简单,放个WebView就ok了,可是返回按钮放在哪 ,ui的设计是在底部显示一个半透明的条,左边有一个返回按钮.这个条显示在内容上面.我有一个担心,就是要是最下 ...