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的从最小到最大的长度,然 ...
随机推荐
- div 弹出 居中
function show_tc_conv(){var x=jq13(window).width()/2;var y=jq13(window).height()/2; var div_w=jq13(& ...
- ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第三天(非原创)
文章大纲 一.课程介绍二.简单功能实现三.图片上传功能实战四.项目源码与资料下载五.参考文章 一.课程介绍 一共14天课程(1)第一天:电商行业的背景.淘淘商城的介绍.搭建项目工程.Svn的使用. ...
- [Android]如何实现无限滚动的ListViw/GridView(翻译)
ListView和GridView已经成为原生的Android应用实现中两个最流行的设计模式.目前,这些模式被大量的开发者使用,主要是因为他们是简单而直接的实现,同时他们提供了一个良好,整洁的用户体验 ...
- 洛谷 P1886 滑动窗口 (数据与其他网站不同。。)
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- AIX 10201 ASM RAC安装+升级到10204
1:查看系统版本 [rac1:root:/hacmp/hacmp5.4/ha5.4/installp/ppc] oslevel -s 6100-06-06-1140 lslpp -al bos.adt ...
- nutwk的maven中央仓库及配置
官方maven服务器:https://jfrog.nutz.cn/artifactory/jcenter/ 如果用阿里的maven服务器,特别提醒:
- HDU_1710_二叉树前序中序确定后序
2018-3-6 按照王道机试书上的思路再做了一遍,先根据先序和中序建树,然后后序遍历. 静态分配数组用于建树,可以返回数组地址当作结点指针. #include<iostream> #in ...
- CSS 文字换行与不换行
1. 强制不换行 p{ white-space:nowrap; } 2. 自动换行 p{ word-wrap: break-word; word-break: normal; } 3. 强制英文单词断 ...
- 谈谈JVM内存区域的划分
我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存,用户缓冲用户IO等待导致CPU的等 ...
- CAD参数绘制文字(网页版)
在CAD设计时,需要绘制文字,用户可以设置设置绘制文字的高度等属性. 主要用到函数说明: _DMxDrawX::DrawText 绘制一个单行文字.详细说明如下: 参数 说明 DOUBLE dPosX ...