http://hihocoder.com/problemset/problem/1337

#1337 : 平衡树·SBT

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小Ho:小Hi,之前你不是讲过Splay和Treap么,那么还有没有更简单的平衡树呢?

小Hi:但是Splay和Treap不是已经很简单了么?

小Ho:是这样没错啦,但是Splay和Treap和原来的二叉搜索树相比都有很大的改动,我有点记不住。

小Hi:这样啊,那我不妨再给你讲解一个新的平衡树算法好了。和二叉搜索树相比,它只需要修改insert函数,就可以做到高度的平衡。

小Ho:好,我就喜欢这样的!

提示:Size Balanced Tree

输入

第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));
}
}
}
}

最新文章

  1. netfilter-在内核态操作网络数据包
  2. C#文件夹和文件操作
  3. java基础之 异常
  4. 【CentOS】samba服务器安装与配置
  5. 【英语】Bingo口语笔记(57) - 常见的口语弱读
  6. 《MFC游戏开发》笔记七 游戏特效的实现(一):背景滚动
  7. Unity3D之Mecanim动画系统学习笔记(三):Animation View
  8. ASP.NET- 合并HTML的表格相同项单元格
  9. perl 正则匹配多个
  10. 数据结构之顺序栈SqStack
  11. CentOS 7.0 systemd代替service
  12. JQuery中Checkbox的一些功能
  13. keybd_event 对应表
  14. http://www.iteye.com/job/topic/1133159
  15. swift 之 namespace
  16. Oracle E-Business Suite Maintenance Guide Release 12.2(Patching Utilities)
  17. go语言使用xpath
  18. 自学Python Day1
  19. POJ 2352 树状数组
  20. 【python】——sql模拟

热门文章

  1. Linq创建带命名空间、前缀、Soap格式的XML
  2. Newtonsoft.Json
  3. selenium测试(Java)--多窗口切换(十三)
  4. JavaScript- jquery easyui 可编辑表格插件 easyui.editgrid
  5. 剑指offer:赋值运算符函数和复制构造函数
  6. asp.net调用客户端WebBrowser 进行网站地址截屏
  7. 刚知道的android属性
  8. 初识NodeJS,一个基于GoogleV8引擎的Javascript运行环境
  9. MySQL导入SQL文件及常用命令
  10. C#字节数组转换成字符串