题目链接:

http://poj.org/problem?id=2104

K-th Number

Time Limit: 20000MSMemory Limit: 65536K

问题描述

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个询问,每个询问给你l,r,k,求(l,r)区间里第k大的数,保证每个数只出现一次。

题解

主席树裸板。
一个简洁形象的教程:[port]
代码:[port]

代码

本土化:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<sstream>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson(i) (tre[(i)].ls)
#define rson(i) (tre[(i)].rs)
#define sumv(i) tre[(i)].sum
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printftypedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);//start----------------------------------------------------------------------const int maxn=1e5+10;///nlogn空间复杂度
struct Tre{int ls,rs,sum;Tre(){ls=rs=sum=0;}
}tre[maxn*20];int n,m;
int rt[maxn],tot;int _v;
void update(int &o,int l,int r){tre[++tot]=tre[o],o=tot;if(l==r){sumv(o)++;}else{if(_v<=mid) update(lson(o),l,mid);else update(rson(o),mid+1,r);sumv(o)=sumv(lson(o))+sumv(rson(o));}
}int _res;
void query(int o1,int o2,int l,int r,int k){if(l==r){_res=l;}else{///前缀和思想int cnt=sumv(lson(o2))-sumv(lson(o1));if(cnt>=k) query(lson(o1),lson(o2),l,mid,k);else query(rson(o1),rson(o2),mid+1,r,k-cnt);}
}int idx[maxn],arr[maxn],ra[maxn];bool cmp(int x,int y){return arr[x]<arr[y];
}///0是个超级节点
void init(){rt[0]=tot=0;
}int main() {while(scf("%d%d",&n,&m)==2&&n){init();for(int i=1;i<=n;i++) scf("%d",&arr[i]);for(int i=1;i<=n;i++) idx[i]=i;///离散化sort(idx+1,idx+n+1,cmp);for(int i=1;i<=n;i++) ra[idx[i]]=i;///主席树for(int i=1;i<=n;i++){_v=ra[i];rt[i]=rt[i-1];update(rt[i],1,n);}///查询区间第k大while(m--){int l,r,k;scf("%d%d%d",&l,&r,&k);query(rt[l-1],rt[r],1,n,k);prf("%d\n",arr[idx[_res]]);}}return 0;
}//end-----------------------------------------------------------------------

转载于:https://www.cnblogs.com/fenice/p/5931542.html

POJ 2104 K-th Number 主席树(区间第k大)相关推荐

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

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

  2. ZOJ 2112 Dynamic Rankings(主席树-动态第k大)

    Description 给出一个长度为n的序列a,两种操作 C x v:将第x个元素的值改成v Q l r k:查询区间[l,r]中第k大的元素 Input 第一行为一个整数t表示用例组数,每组用例第 ...

  3. HDU2665(函数式线段树-区间第K大)

    题目:K-th Number 如果求区间第K小,就转换一下就行了,假设你要求区间[u,v]的第k小,那就是第v-u+1-k大 #include<stdio.h> #include<a ...

  4. HDU 4348 To the moon(主席树区间修改)

    题意 给你一个区间,支持如下操作: 在一段区间内加上一个值,并生成一个历史版本 查询某个版本下一段区间内的和 回到一个历史版本上并舍弃之后的版本 做法 这就是主席树区间修改裸题啦QwQ 上一篇博客我讲 ...

  5. PAT (Basic Level) Practise 1045 快速排序(离散化+主席树区间内的区间求和)

    1045. 快速排序(25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 著名的快速排序算法里有一个经典的划分 ...

  6. POJ - 2104 K-th Number(主席树)

    题目链接:点击查看 题目大意:给出一个数列,然后是m次查询,每次查询闭区间[l,r]内第K大的数 题目分析:裸的主席树,暑假集训第三周的时候就听说过了这个数据结构,不过当时太懒了,而且那些主席树的问题 ...

  7. K-th Closest Distance HDU - 6621(第k小绝对值+主席树+二分)

    You have an array: a1, a2, , an and you must answer for some queries. For each query, you are given ...

  8. CodeForces - 484E Sign on Fence(主席树区间合并+二分)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的数列,需要回答 mmm 次询问,每次询问的格式如下: lrkl\ r\ kl r k,需要回答区间 [l,r][l,r][l,r] 内,所有长度 ...

  9. HDU - 4348 To the moon(主席树区间更新-标记永久化)

    题目链接:点击查看 题目大意:给出一个初始时长度为 n 的序列,有 m 次操作,每种操作分为下列四种类型: C l r d:新建一个继承了前一个版本的数组,并将区间 [ l , r ] 内的数字都加上 ...

最新文章

  1. k8s概念入门之control-manager-针对1.1.版本阅读
  2. 基于模型的系统工程设计软件ModelCoder在航空发动机控制设计中的应用
  3. flv 开源 修复_解决开源项目错误和修复的5个步骤
  4. Python机器学习:梯度下降法002模拟实现梯度下降法
  5. WebSocket和WebRtc的一些心得
  6. 自带CA ,sha256 哈希签名,2048 位加密 脚本,通用
  7. shiro放行_Shiro框架详解
  8. C# Hprose轻量级、跨语言、跨平台的面向对象的高性能远程动态通讯中间件
  9. 我是如何获得微信内置表情的
  10. 发那科机器人回原位置先上升_发那科机器人offset condition 指令什么意思
  11. 让windows保持常亮(不息屏,不锁屏,不进入屏保)
  12. 你这简历一看就是包装过的
  13. VLAN隔离思维导图
  14. python02 函数 等额本金贷款
  15. QQ音乐关键字搜索并生成下载url
  16. Java如何输入一个不知道长度的数组
  17. 华为申请区块链产权管理专利
  18. kali系统的u盘安装过程_kali linux怎么安装u盘启动
  19. 分享150个ASP源码,总有一款适合您
  20. mysql学生班级老师_MySQL全方位练习(学生表 教师表 课程表 分数表)

热门文章

  1. django mac 安装mysql_mac安装MySQL-Python报错
  2. matlab 释放变量,怎么能释放已经使用的内存
  3. mysql api是什么意思_什么是mysql c api? 解析mysql c api简单应用
  4. oracle dba 命令行,Oracle DBA常用命令
  5. java物品类_Java:类中的所有东西都是静态的 – 这是合理的吗?
  6. File转换成MultiPartFile
  7. Jmeter模拟加密密码登录
  8. 【CCCC】PAT : 团体程序设计天梯赛-练习集 L2 答案,题解,附代码
  9. C++复制粘贴代码去行标
  10. 【图论】最小生成树学习笔记