http://hihocoder.com/problemset/problem/1337
#1337 : 平衡树·SBT
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小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
解法一 使用二叉搜索树:
1 import java.util.Scanner; 2 3 /** 4 * author: 龚细军 5 * class-aim: 6 */ 7 8 class Node { 9 public Integer key; 10 public long size; 11 public Node left; 12 public Node right; 13 14 public Node() { 15 size = 0; 16 key = null; 17 left = right = null; 18 } 19 } 20 21 /*二叉排序树,此题不需要调解平衡*/ 22 class BSTree { 23 private static final int DEFAULT_INITIAL_CAPACITY = 1; 24 25 public static int query(Node node, int kMin) { 26 Long flag = node.left.size - kMin + 1; 27 if (flag == 0) return node.key; 28 if (flag < 0) return query(node.right, (int) abs(flag)); 29 return query(node.left, kMin); 30 } 31 32 private static long abs(Long flag) { 33 return flag > 0 ? flag : -1 * flag; 34 } 35 36 public static void insert(Node node, int data) { 37 if (node.size > 0) { 38 node.size++; 39 insert(data > node.key ? node.right : node.left, data); 40 } else { 41 node.key = data; 42 node.size = DEFAULT_INITIAL_CAPACITY; 43 node.left = new Node(); 44 node.right = new Node(); 45 } 46 } 47 48 } 49 50 public class Main { 51 52 public static void main(String args[]) { 53 int num, val; 54 String cmd; 55 Scanner scanner = new Scanner(System.in); 56 while (scanner.hasNext()) { 57 num = scanner.nextInt(); 58 Node root = new Node(); 59 while (num-- > 0) { 60 cmd = scanner.next(); 61 val = scanner.nextInt(); 62 if (cmd.equals("I")) BSTree.insert(root, val); 63 else { 64 System.out.println(BSTree.query(root, val)); 65 } 66 } 67 } 68 } 69 70 }
解法二: SBT树
1 import java.util.Scanner; 2 3 /** 4 * author: 龚细军 5 * class-aim: 6 */ 7 8 class Node { 9 public int key, size; 10 public Node left, right; 11 } 12 13 public class Main { 14 private static final int DEFAULT_INITIAL_CAPACITY = 1; 15 16 public static int getSize(Node node) { 17 return node == null ? 0 : node.size; 18 } 19 20 public static int compare(Node a, Node b) { 21 return a.key - b.key; 22 } 23 24 public static int compare(Node a, int key) { 25 return a.key - key; 26 } 27 28 public static void update(Node node) { 29 if (node == null) return; 30 node.size = getSize(node.left) + getSize(node.left) + 1; 31 } 32 33 public static void rightRotate(Node master, Node node) { 34 master.left = node.right; 35 node.right = master; 36 update(master); 37 update(node); 38 master = node; 39 } 40 41 public static void leftRotate(Node master, Node node) { 42 master.right = node.left; 43 node.left = master; 44 update(node); 45 update(master); 46 master = node; 47 } 48 49 public static void insert(Node master, int key) { 50 51 if (master.size == 0) { 52 master.left = new Node(); 53 master.right = new Node(); 54 master.size = DEFAULT_INITIAL_CAPACITY; 55 master.key = key; 56 } else if (compare(master, key) > 0) { 57 insert(master.left, key); 58 if (getSize(master.left.left) > getSize(master.right)) { 59 //右旋转 60 rightRotate(master, master.left); 61 } 62 } else { 63 insert(master.right, key); 64 if (getSize(master.right.right) > getSize(master.left)) { 65 //左旋转 66 leftRotate(master, master.right); 67 } 68 } 69 70 update(master); 71 72 } 73 74 private static int abs(int flag) { 75 return flag > 0 ? flag : -1 * flag; 76 } 77 78 public static int query(Node node, int kMin) { 79 int flag = node.left.size - kMin + 1; 80 if (flag == 0) return node.key; 81 if (flag < 0) return query(node.right, (int) abs(flag)); 82 return query(node.left, kMin); 83 } 84 85 public static void main(String args[]) { 86 int num, val; 87 String cmd; 88 Scanner scanner = new Scanner(System.in); 89 while (scanner.hasNext()) { 90 num = scanner.nextInt(); 91 Node root = new Node(); 92 while (num-- > 0) { 93 cmd = scanner.next(); 94 val = scanner.nextInt(); 95 if (cmd.equals("I")) 96 Main.insert(root, val); 97 else 98 System.out.println(Main.query(root, val)); 99 } 100 } 101 } 102 }
时间: 2024-10-11 17:56:19