基准时间限制: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. C#-#define条件编译

    本文导读: C#的预处理器指令从来不会转化为可执行代码的命令,但是会影响编译过程的各个方面,常用的预处理器指令有#define.#undef.#if,#elif,#else和#endif等等,下面介绍 ...

  2. javascript之标识(zhi)符、关键字与保留字

    正确区分标识(zhi)符.关键字与保留字 我发现很多初学者往往弄不清楚这三者的区别,甚至会把标识符的“识(zhi)”读作识(shi),真是愧对小学的语文老师啊!!! 注意:在JavaScript中,所 ...

  3. 【LAMP】在Debian系linux下安装LAMP

    一.安装基本的编译环境 apt-get install build-essential 二.安装MySQL apt-get install mysql-server 三.安装Apache apt-ge ...

  4. python学习札记(1)

    首先给大家推荐一个很好的python入门网站,感觉比<python基础>之类的书更容易懂,廖雪峰小站,希望有学习资源同学们也能多多交流.下面是今天所学: 下面总结一些非常有特色的函数及其应 ...

  5. 基于Socket的UDP发包程序

    UDP(User Datagram Protocol,用户数据报协议)是在互联网中常用的传输层协议,该协议提供了向另一用户程序发送的消息的最简便的协议机制.与TCP一样,其默认的下层协议是IP.UDP ...

  6. WPF 格式化输出- IValueConverter接口的使用

    以前在用ASP.NET 做B/S系统时,可以方便地在GRIDVIEW DATAList等数据控件中,使用自定义的代码逻辑,比如 使用 <%# GetBalance(custID) %> 这 ...

  7. JavaScript--Date函数

    1. Date函数 var now = new Date(); 获取当前日期对象 now对象->Date.prototype->Object.prototype 将一个字符串转换为Date ...

  8. android传送照片到FTP服务器

    package com.photo; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundE ...

  9. 自己动手写处理器之第一阶段(2)——MIPS指令集架构的演变

    将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第三篇.我尽量每周四篇 MIPS指令集架构自上世纪80年代出现后.一直在进行着更新换代,从最初的MIPS I到MIPS V,发 ...

  10. ubuntu root 设置

    ubuntu16.04的root初始密码是随机的,每次开机都有一个新的root密码.具体修改方法是:sudo passwd输入自己用户名密码输入root密码su root输入密码登录