51nod p1175 区间中第K大的数
一个长度为N的整数序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,第K大的数是多少。
例如: 1 7 6 3 1。i = 1, j = 3,k = 2,对应的数为7 6 3,第2大的数为6。
Input
第1行:1个数N,表示序列的长度。(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列中的元素。(0 <= S[i] <= 10^9) 第N + 2行:1个数Q,表示查询的数量。(2 <= Q <= 50000) 第N + 3 - N + Q + 2行:每行3个数,对应查询的起始编号i和结束编号j,以及k。(0 <= i <= j <= N - 1,1 <= k <= j - i + 1)
Output
共Q行,对应每一个查询区间中第K大的数。
Input示例
5 1 7 6 3 1 3 0 1 1 1 3 2 3 4 2
Output示例
7 6 1
区间第k大,主席树写一发,使用java写的,顺便复习
吐槽---java真是慢,一定要离散化,c++随便写都过
而且没有sort,没有map,只有hashmap,真逊啊。。。。
1 package p1175; 2 3 import java.io.*; 4 import java.util.*; 5 6 import javax.management.Query; 7 8 public class Main 9 { 10 public static class Node 11 { 12 int sum; 13 Node lc, rc; 14 public Node(Node t) 15 { 16 if(t == null) 17 { 18 lc = rc = null; 19 sum = 0; 20 } 21 else 22 { 23 lc = t.lc; 24 rc = t.rc; 25 sum = t.sum; 26 } 27 } 28 } 29 30 static final int N = 50010; 31 32 public static void main(String[] args) throws IOException 33 { 34 // TODO Auto-generated method stub 35 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 36 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); 37 int n = getInt(reader); 38 int[] arr = new int[n], store = new int[n]; 39 for(int i = 0; i < n; i++) store[i] = arr[i] = getInt(reader); 40 mergeSort(store, 0, n - 1); 41 int len = 1; 42 for(int i = 1; i < n; i++) 43 if(store[i] != store[i - 1]) store[len++] = store[i]; 44 HashMap<Integer, Integer> myMap = new HashMap<Integer, Integer>(); 45 for(int i = 0; i < len; i++) 46 myMap.put(store[i], i); 47 for(int i = 0; i < n; i++) 48 arr[i] = myMap.get(arr[i]); 49 50 51 Node[] root = new Node[n + 1]; 52 Node last = null; 53 for(int i = 0; i < n; i++) 54 { 55 root[i] = new Node(last); 56 buildTree(root[i], arr[i], 0, len); 57 last = root[i]; 58 } 59 60 for(int m = getInt(reader); m > 0; m--) 61 { 62 int l = getInt(reader), r = getInt(reader), k = getInt(reader); 63 int ans = queryKth(l > 0 ? root[l - 1] : null, root[r], k, 0, len); 64 writer.write(store[ans] + "\r\n"); 65 writer.flush(); 66 } 67 } 68 69 public static int querySum(Node t) 70 { 71 if(t == null) return 0; 72 return t.sum; 73 } 74 75 public static int queryKth(Node l, Node r, int kth, int left, int right) 76 { 77 if(left == right) return left; 78 int mid = (left + right) >> 1, ret = -1; 79 int lCnt = l == null ? 0 : querySum(l.rc), rCnt = r == null ? 0 : querySum(r.rc); 80 if(rCnt - lCnt >= kth) ret = queryKth(l == null ? null : l.rc, r == null ? null : r.rc, kth, mid + 1, right); 81 else ret = queryKth(l == null ? null : l.lc, r == null ? null : r.lc, kth - (rCnt - lCnt), left, mid); 82 return ret; 83 } 84 85 public static void buildTree(Node x, int val, int left, int right) 86 { 87 if(left < right) 88 { 89 int mid = (left + right) >> 1; 90 if(val <= mid) 91 { 92 x.lc = new Node(x.lc); 93 buildTree(x.lc, val, left, mid); 94 } 95 else 96 { 97 x.rc = new Node(x.rc); 98 buildTree(x.rc, val, mid + 1, right); 99 } 100 } 101 x.sum++; 102 } 103 104 static int[] tmp = new int[N]; 105 public static void mergeSort(int[] arr, int l, int r) 106 { 107 if(l >= r) return; 108 int mid = (l + r) >> 1; 109 mergeSort(arr, l, mid); 110 mergeSort(arr, mid + 1, r); 111 int itL = l, itR = mid + 1, now = l; 112 while(itL <= mid && itR <= r) 113 { 114 if(arr[itL] < arr[itR]) tmp[now++] = arr[itL++]; 115 else tmp[now++] = arr[itR++]; 116 } 117 while(itL <= mid) tmp[now++] = arr[itL++]; 118 while(itR <= r) tmp[now++] = arr[itR++]; 119 for(int i = l; i <= r; i++) arr[i] = tmp[i]; 120 } 121 122 public static int getInt(BufferedReader reader) throws IOException 123 { 124 char ch = ' '; 125 for( ; !(ch >= '0' && ch <= '9'); ch = (char) reader.read()) ; 126 int ret = 0; 127 for( ; ch >= '0' && ch <= '9'; ch = (char) reader.read()) 128 ret = ret * 10 + ch - '0'; 129 return ret; 130 } 131 132 }