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的从最小到最大的长度,然 ...
随机推荐
- 自己制作ssl证书
首先执行如下命令生成一个key openssl genrsa -des3 -out ssl.key 1024 然后他会要求你输入这个key文件的密码.不推荐输入.因为以后要给nginx使用.每次r ...
- Spring @Resource、@Autowired、@Qualifier区别
@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入: @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualif ...
- [转]Business Model Canvas(商业模式画布):创业公司做头脑风暴和可行性测试的一大利器
本文转自:http://www.36kr.com/p/214438.html 本文来自First Round Review,他们准备的文章既讲故事,还同时向创业者提供可操作的建议,以助力打造优秀的公司 ...
- sql server添加用户和给用户授权
--创建用户CREATE LOGIN 用户名 WITH PASSWORD=N'密码', DEFAULT_DATABASE=数据库名, CHECK_EXPIRATION=OFF, CHECK_POLIC ...
- 手机端左右滑动,不用写js(只有页面切换到移动端可以看)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Proc datasets
作用:控制数据集.Datasets 过程运行结果不输出,结果只有在日志里才能看到. 基本语法: proc datasets lib=work; quit; 用法: 1. 更改数据集 proc data ...
- java的回调方式
经常写js的回调,js的回调很简单,直接传方法名称,但是java中方法不能作为参数传递 但是java中可以传一个对象,在对象中编写多个方法,然后作为参数传递到对象里以后,就可以在适当的时机调用该对象里 ...
- 利用jquery制作滚动到指定位置触发动画
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>利用 ...
- 获取当前时间(日期格式) && 获取当前加一年的时间(日期格式)
获取当前时间,日期格式function currentDate() { var date = new Date(); var y = date.getFullYear(); var m = date. ...
- 查找BUG的方法
1)测试环境 1)代码调试 2)问题重现 3)思考问题所在 2)生产环境 1)思考 2)测试本地环境是否存在问题 3)打开日志查看 4)思考是否是数据原因 5)拷贝数据到本地进行重现 3)未知错误 1 ...