51nod p1175 区间中第K大的数

Posted Stupidboy is here!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod p1175 区间中第K大的数相关的知识,希望对你有一定的参考价值。

基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
 
一个长度为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 }
View Code

 

以上是关于51nod p1175 区间中第K大的数的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1105 第K大的数

51Nod - 1105 第K大的数

51nod1711 平均数

51nod 平均数(二分+树状数组)

51nod 平均数(马拉松14)

51 nod 1105 第K大的数