hihocoder-平衡树·SBT
2016-07-17 14:19
387 查看
http://hihocoder.com/problemset/problem/1337
单点时限:1000ms
内存限制:256MB
小Hi:但是Splay和Treap不是已经很简单了么?
小Ho:是这样没错啦,但是Splay和Treap和原来的二叉搜索树相比都有很大的改动,我有点记不住。
小Hi:这样啊,那我不妨再给你讲解一个新的平衡树算法好了。和二叉搜索树相比,它只需要修改insert函数,就可以做到高度的平衡。
小Ho:好,我就喜欢这样的!
提示:Size Balanced Tree
第2..n+1行:每行1个字母c和1个整数k:
若c为'I',表示插入一个数字k到树中,-1,000,000,000≤k≤1,000,000,000
若c为'Q',表示询问树中第k小数字,保证1≤k≤树的节点数量
样例输入
样例输出
---恢复内容结束---
动态查询Ktop系列
1.对于固定的Ktop系列,可以使用 优先队列,最小堆,Treap,BST,SBT
2.动态的Ktop Treap,BST,SBT 效率: BST<Treap<SBT
解法一 使用二叉搜索树: 此方法是直接建立起二叉树,对于树不做调整,这会造成树变得很长!
遇到的坑: Java swap不能像C++那样,C++可以传地址,传值,传应用但是Java并不是,Java只能传值,并且传递参数的时候,使用的是深copy,也就是参数的对象和本尊不是同一个对象地址,而仅仅是和它拥有相同数值的不同对象。所以swap不能像C++那样.
解法二: 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)
#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)); } } } }
相关文章推荐
- 利用 libevent 实现简单 http client GET、POST
- handler浅谈
- HTML iframe 用法小总结
- linux系统中怎么结束boa进程?
- gcc选项 -D_REENTRANT机制
- 晃动动画加震动
- jzoj 1591. 【普及模拟】游戏
- listView分页加载
- 根据观测时间,经纬度,求太阳高度角
- win7 vi工具
- cccc
- java文件及读写操作
- Gift (Standard IO)
- <s:iterator/>标签取循环索引的问题
- ClamAV
- Circle (Standard IO)
- IMS Modify Call (3) accept reject timeout 接受/拒接/超时 视频升级请求
- Linux服务器程序规范
- AV Foundation系列(四)AVAssetReader和AVAssetWrite
- NO6 软件开发项目维护的开发可行性方案 (设计三步之二)