POJ 2104 K-th Number (可持久化线段树)
题目大意
给一个长度为n的序列,有m个询问,每次询问一个区间里面第k小的数。
解题分析
静态的区间第k大。复习了一下可持久化线段树。
首先对数值离散化,建一颗权值线段树。按照序列的顺序依次插入,每一个数对应于一个版本的线段树。
对于每个询问[l,r],在第r个版本的线段树和第l个版本的线段树之间进行查询。
本质上来说,可持久化线段树干了一件前缀和的事情,每棵线段树记录了1~i序列的权值信息。
参考程序
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100008;
int a[N],x[N],rt[N],ls[N*20],rs[N*20],sum[N*20];
int tot,n,m;
void build(int l,int r,int &rt)
{
rt=++tot;
sum[rt]=0;
if (l==r) return;
int m=l+r>>1;
build(l,m,ls[rt]);
build(m+1,r,rs[rt]);
}
void insert(int val,int l,int r,int &rt,int last)
{
rt=++tot;
ls[rt]=ls[last]; rs[rt]=rs[last]; sum[rt]=sum[last]+1;
if (l==r) return;
int m=l+r>>1;
if (val<=m) insert(val,l,m,ls[rt],ls[last]);
else insert(val,m+1,r,rs[rt],rs[last]);
}
int query(int k,int l,int r,int L,int R)
{
if (l==r) return x[l];
int m=l+r>>1;
if (sum[ls[R]]-sum[ls[L]]>=k) return query(k,l,m,ls[L],ls[R]);
else return query(k-(sum[ls[R]]-sum[ls[L]]),m+1,r,rs[L],rs[R]);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) {scanf("%d",&a[i]);x[i]=a[i];}
sort(x+1,x+n+1);
int nn=unique(x+1,x+n+1)-x-1;
build(1,nn,rt[0]);
for (int i=1;i<=n;i++)
{
int y=lower_bound(x+1,x+nn+1,a[i])-x;
insert(y,1,nn,rt[i],rt[i-1]);
}
for (int i=1;i<=m;i++)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",query(k,1,nn,rt[l-1],rt[r]));
}
}
POJ 2104 K-th Number (可持久化线段树)的更多相关文章
- [POJ2104] K – th Number (可持久化线段树 主席树)
题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...
- SPOJ-COT-Count on a tree(树上路径第K小,可持久化线段树)
题意: 求树上A,B两点路径上第K小的数 分析: 同样是可持久化线段树,只是这一次我们用它来维护树上的信息. 我们之前已经知道,可持久化线段树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表 ...
- hihocoder#1046 K个串 可持久化线段树 + 堆
首先考虑二分,然后发现不可行.... 注意到\(k\)十分小,尝试从这里突破 首先用扫描线来处理出以每个节点为右端点的区间的权值和,用可持久化线段树存下来 在所有的右端点相同的区间中,挑一个权值最大的 ...
- 【BZOJ4504】K个串 可持久化线段树+堆
[BZOJ4504]K个串 Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计 ...
- bzoj 4504: K个串 可持久化线段树+堆
题目: Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想 ...
- [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]
可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...
- 树上第k小,可持久化线段树+倍增lca
给定一颗树,树的每个结点都有权值, 有q个询问,每个询问是 u v k ,表示u到v路径上第k小的权值是多少. 每个结点所表示的线段树,是父亲结点的线段树添加该结点的权值之后形成的新的线段树 c[ro ...
- HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- K-th Number 【POJ - 2104】【可持久化线段树】
题目链接 因为这道题没有删除修改之类的,所以很多人会用离散化之后的线段树来做,但是实际上(可能是我懒得去做离散化这个操作了),然后就是直接写可持久化线段树,区间的长度就是int的从最小到最大的长度,然 ...
随机推荐
- Redis和SpringDataRedis
一.Redis简介 Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,运行在内存中,由ANSI C编写.企业开发通常采用Redis来实现缓存.同类的产品还有memcac ...
- 掌握Spark机器学习库-07-最小二乘法
1)最小化残差平方和 2)原理,推导过程 3)例子
- iOS programming UITableView and UITableViewController
iOS programming UITableView and UITableViewController A UITableView displays a single column of dat ...
- iOS Programming View Controllers 视图控制器
iOS Programming View Controllers 视图控制器 1.1 A view controller is an instance of a subclass of UIVi ...
- JData 整合ArtTemplate的前端框架
因为项目需要和自己的兴趣,几个月前结合模板解析神速的ArtTemplate,自己写了个框架取名JData,多多指教啊---因为一直没时间写文档,为了能够更方便地使用和避免我把代码忘了,今天抽空把文档写 ...
- yii项目开发配置
Clone项目 git clone https://gitee.com/s***/dianshang.git 安装yii php ini 选择 [0] Development 安装扩展 copy co ...
- ubuntu命令行使用ftp客户端
转载 本篇文章主要介绍在Ubuntu 8.10下如何使用功能强大的FTP客户端软件NcFTP. Ubuntu的源里为我们提供了FTP客户端软件NcFTP,可这款工具对新手来说不是很方便.本文介绍的是一 ...
- glm 矩阵乘法得反过来写
- 3D旋转矩阵的推导过程
3D旋转矩阵的推导过程 包含平移的线性变换称作仿射变换,3D中的仿射变换不能用 3 x 3 矩阵表达,必须使用4 x 4矩阵. 一般来说,变换物体相当于以相反的量变换描述这个物体的坐标系.当有多个变换 ...
- C#在sql中使用變量訪問Oracle數據庫
1.首先創建一個測試數據表 CREATE TABLE people ( SNO BYTE), SNAME BYTE), SSEX BYTE), SAGE number, SDEPT BYTE), BT ...