题目描述

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. 
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?" 
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.

输入

The first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000). 
The second line contains n different integer numbers not exceeding 109 by their absolute values --- the array for which the answers should be given. 
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).

输出

For each question output the answer to it --- the k-th number in sorted a[i...j] segment.

样例输入

7 3

1 5 2 6 3 7 4

2 5 3

4 4 1

1 7 3

样例输出

5

6

3


题目大意

给你n个数和m组询问,对于每组询问输出区间[i,j]中第k大的数是多少。

题解

主席树模板题。

先将数据离散化,然后加入到n棵动态开点线段树中。

由于每次只修改一个值,所以其余的子节点可以直接继承上一个子节点。

查询时,直接作差即可。

#include <cstdio>
#include <algorithm>
using namespace std;
struct data
{
int num , pos;
}a[100010];
int lp[4000010] , rp[4000010] , sum[4000010] , root[100010] , val[100010] , tot , cnt;
bool cmp1(data a , data b)
{
return a.num < b.num;
}
bool cmp2(data a , data b)
{
return a.pos < b.pos;
}
void pushup(int x)
{
sum[x] = sum[lp[x]] + sum[rp[x]];
}
void ins(int x , int &y , int l , int r , int p)
{
y = ++tot;
if(l == r)
{
sum[y] = sum[x] + 1;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) rp[y] = rp[x] , ins(lp[x] , lp[y] , l , mid , p);
else lp[y] = lp[x] , ins(rp[x] , rp[y] , mid + 1 , r , p);
pushup(y);
}
int query(int x , int y , int l , int r , int p)
{
if(l == r) return val[l];
int mid = (l + r) >> 1;
if(sum[lp[y]] - sum[lp[x]] >= p) return query(lp[x] , lp[y] , l , mid , p);
else return query(rp[x] , rp[y] , mid + 1 , r , p - sum[lp[y]] + sum[lp[x]]);
}
int main()
{
int n , m , i , x , y , z;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ )
scanf("%d" , &a[i].num) , a[i].pos = i;
sort(a + 1 , a + n + 1 , cmp1);
val[0] = 0x80000000;
for(i = 1 ; i <= n ; i ++ )
{
if(a[i].num > val[cnt]) val[++cnt] = a[i].num;
a[i].num = cnt;
}
sort(a + 1 , a + n + 1 , cmp2);
for(i = 1 ; i <= n ; i ++ )
ins(root[i - 1] , root[i] , 1 , cnt , a[i].num);
for(i = 1 ; i <= m ; i ++ )
{
scanf("%d%d%d" , &x , &y , &z);
printf("%d\n" , query(root[x - 1] , root[y] , 1 , cnt , z));
}
}

【poj2104】K-th Number 主席树的更多相关文章

  1. poj2104 k-th number 主席树入门讲解

    poj2104 k-th number 主席树入门讲解 定义:主席树是一种可持久化的线段树 又叫函数式线段树   刚开始学是不是觉得很蒙逼啊 其实我也是 主席树说简单了 就是 保留你每一步操作完成之后 ...

  2. poj 2104 K-th Number 主席树+超级详细解释

    poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...

  3. [POJ2104] K – th Number (可持久化线段树 主席树)

    题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...

  4. poj2104 K-th Number区间第k小值 主席树

    原来主席树就是可持久化线段树啊,刚知道,,, 作为一道裸题,还是必A的,然而一开始偷懒不写离散化跪了N多遍,后来在缪大的帮助下发现了这个问题,遂A之 ——又是这种破问题,实在不想说自己了 把n个数看成 ...

  5. 【POJ2104】【HDU2665】K-th Number 主席树

    [POJ2104][HDU2665]K-th Number Description You are working for Macrohard company in data structures d ...

  6. POJ2104 K-th Number[主席树]【学习笔记】

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 51440   Accepted: 17594 Ca ...

  7. [poj2104] K-th Number (主席树)

    主席树 Description You are working for Macrohard company in data structures department. After failing y ...

  8. 主席树:POJ2104 K-th Number (主席树模板题)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 44952   Accepted: 14951 Ca ...

  9. POJ 2104 K-th Number 主席树(区间第k大)

    题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...

随机推荐

  1. CSS基础part1

    CSS 概述CSS 指层叠样式表 (Cascading Style Sheets),样式定义了如何显示 HTML文件中的标签元素,CSS是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标 ...

  2. java生成PDF,并下载到本地

    1.首先要写一个PDF工具类,以及相关工具 2.PDF所需jar包 iText是一种生成PDF报表的Java组件 freemarker是基于模板来生成文本输出 <dependency> & ...

  3. 常用排序算法的C++实现

    排序是将一组"无序"的记录序列调整为"有序"的记录序列. 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在 ...

  4. EWS3-24S05电源转换芯片DC-DC

    1. EWS3-24S05是24V转5V的DC-DC电源,输入和输出都是直流电. 2. 典型应用 3. 引脚图 4. 使用注意事项: 输入电源的要求 输入电源的要求产品的输入端必需接一个低阻抗的电压源 ...

  5. iOS 测试工具reveal可视化调试工具的使用

    简单翻译一下reveal可视化图形工具插入项目的官方文档(官方英文版file:///Applications/Reveal.app/Contents/SharedSupport/Documentati ...

  6. C# 浮点转时间

    想了大半天实在想不出什么更适合文章的标题... 就现在这个标题,挺好- - 什么是浮点转时间呢? 今天写的一个计时功能,想来想去还是现在这种解决方案比较合适 先上一张图在来讲解比较明了 如图:赛车游戏 ...

  7. 2019年猪年海报PSD模板-第六部分

    14套精美猪年海报,免费猪年海报,下载地址:百度网盘,https://pan.baidu.com/s/1WdlIiIdj1VVWxI4je0ebKw            

  8. 「日常训练」Maximum Multiple(HDU-6298)

    题意与分析 一开始以为是一条高深的数学题,跳过去了,后来查其他题目的代码的时候无意看到,一看emmmmmm 稍微思考一下就有了.\(1=\frac{1}{3}+\frac{1}{3}+\frac{1} ...

  9. 感觉总结了一切python常见知识点,可直接运行版本

    #encoding=utf-8#http://python.jobbole.com/85231/#作用域a=1def A(a): a=2 print 'A:',a def B(): print 'B: ...

  10. VBS简明教程

    VBS简明教程   一.输出 VBS的输出使用函数Msgbox调用对话框进行输出. Msgbox(message) Message为要输出的信息 二.输入 VBS的输入,调用函数Inputbox()进 ...