基准时间限制: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,真逊啊。。。。
 package p1175;

 import java.io.*;
import java.util.*; import javax.management.Query; public class Main
{
public static class Node
{
int sum;
Node lc, rc;
public Node(Node t)
{
if(t == null)
{
lc = rc = null;
sum = 0;
}
else
{
lc = t.lc;
rc = t.rc;
sum = t.sum;
}
}
} static final int N = 50010; public static void main(String[] args) throws IOException
{
// TODO Auto-generated method stub
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
int n = getInt(reader);
int[] arr = new int[n], store = new int[n];
for(int i = 0; i < n; i++) store[i] = arr[i] = getInt(reader);
mergeSort(store, 0, n - 1);
int len = 1;
for(int i = 1; i < n; i++)
if(store[i] != store[i - 1]) store[len++] = store[i];
HashMap<Integer, Integer> myMap = new HashMap<Integer, Integer>();
for(int i = 0; i < len; i++)
myMap.put(store[i], i);
for(int i = 0; i < n; i++)
arr[i] = myMap.get(arr[i]); Node[] root = new Node[n + 1];
Node last = null;
for(int i = 0; i < n; i++)
{
root[i] = new Node(last);
buildTree(root[i], arr[i], 0, len);
last = root[i];
} for(int m = getInt(reader); m > 0; m--)
{
int l = getInt(reader), r = getInt(reader), k = getInt(reader);
int ans = queryKth(l > 0 ? root[l - 1] : null, root[r], k, 0, len);
writer.write(store[ans] + "\r\n");
writer.flush();
}
} public static int querySum(Node t)
{
if(t == null) return 0;
return t.sum;
} public static int queryKth(Node l, Node r, int kth, int left, int right)
{
if(left == right) return left;
int mid = (left + right) >> 1, ret = -1;
int lCnt = l == null ? 0 : querySum(l.rc), rCnt = r == null ? 0 : querySum(r.rc);
if(rCnt - lCnt >= kth) ret = queryKth(l == null ? null : l.rc, r == null ? null : r.rc, kth, mid + 1, right);
else ret = queryKth(l == null ? null : l.lc, r == null ? null : r.lc, kth - (rCnt - lCnt), left, mid);
return ret;
} public static void buildTree(Node x, int val, int left, int right)
{
if(left < right)
{
int mid = (left + right) >> 1;
if(val <= mid)
{
x.lc = new Node(x.lc);
buildTree(x.lc, val, left, mid);
}
else
{
x.rc = new Node(x.rc);
buildTree(x.rc, val, mid + 1, right);
}
}
x.sum++;
} static int[] tmp = new int[N];
public static void mergeSort(int[] arr, int l, int r)
{
if(l >= r) return;
int mid = (l + r) >> 1;
mergeSort(arr, l, mid);
mergeSort(arr, mid + 1, r);
int itL = l, itR = mid + 1, now = l;
while(itL <= mid && itR <= r)
{
if(arr[itL] < arr[itR]) tmp[now++] = arr[itL++];
else tmp[now++] = arr[itR++];
}
while(itL <= mid) tmp[now++] = arr[itL++];
while(itR <= r) tmp[now++] = arr[itR++];
for(int i = l; i <= r; i++) arr[i] = tmp[i];
} public static int getInt(BufferedReader reader) throws IOException
{
char ch = ' ';
for( ; !(ch >= '0' && ch <= '9'); ch = (char) reader.read()) ;
int ret = 0;
for( ; ch >= '0' && ch <= '9'; ch = (char) reader.read())
ret = ret * 10 + ch - '0';
return ret;
} }

51nod p1175 区间中第K大的数的更多相关文章

  1. 51Nod 1175 区间中第K大的数 (可持久化线段树+离散)

    1175 区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有 ...

  2. 51nod 区间中第K大的数

    区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB  一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,第K大的数是多少. 例如: 1 7 6 ...

  3. 51nod1175 区间中第K大的数

    裸的主席树. #include<cstdio> #include<cstring> #include<cctype> #include<algorithm&g ...

  4. 51NOD 1105 第K大的数

    数组A和数组B,里面都有n个整数. 数组C共有n^2个整数,分别是: A[0] * B[0],A[0] * B[1] ...... A[0] * B[n-1] A[1] * B[0],A[1] * B ...

  5. AC日记——第K大的数 51nod 1105

    1105 第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * ...

  6. 51nod 1105 第K大的数 【双重二分/二分套二分/两数组任意乘积后第K大数】

    1105 第K大的数  基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * ...

  7. 51nod 1105:第K大的数

    1105 第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * ...

  8. [51NOD1105]第k大的数(二分答案)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105 先排序,二分上下界分别是最小的两个数和最大的两个数的乘积 ...

  9. POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)

    传送门 The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8690   Acce ...

随机推荐

  1. 开启后台 Service 闪退

    04-29 15:36:23.395: E/ActivityThread(15275): Performing stop of activity that is not resumed: {com.e ...

  2. gcc创建和使用静态库、动态库

    http://www.cnblogs.com/dyllove98/archive/2013/06/25/3155599.html 目录树结构: test/include/hello.h #ifdef ...

  3. java的system.arraycopy()方法

    java.lang.System的静态方法arraycopy()可以实现数组的复制,讲课的老师说这个方法效率比较高,如果数组有成千上万个元素,那么用这个方法,比用for语句循环快不少.于是我试了试,发 ...

  4. PHP面向对象——重写与重载

    重写/覆盖           override 指:子类重写了父类的同名方法 class Human{    public function say($name){           echo $ ...

  5. logstash json和rubydebug 第次重启logstash都会把所有的日志读完 而不是只读入新输入的内容

    查看一下agent端的shipper的配置: # cat logstash_test2.shipper.conf input { file { path => ["/apps/logs ...

  6. C#的扩展方法

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  7. 重温WCF之数据契约和序列化(四)

    一.数据契约 1.使用数据协定可以灵活控制哪些成员应该被客户端识别. [DataContract] public class Employee { [DataMember] public string ...

  8. 【hdu 1060】【求N^N最低位数字】

    Leftmost Digit Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  9. PostgreSQL简单介绍

    自从MySQL被Oracle收购以后,PostgreSQL逐渐成为开源关系型数据库的首选. 本文介绍PostgreSQL的安装和基本用法,供初次使用者上手.以下内容基于Debian操作系统,其他操作系 ...

  10. PGA

    Server Process PGA   1.PGA作用   2.PGA構成      1)private sql area      2)session memory          3)sql ...