poj2104 K-th Number 离散+可持久化线段树
来源:互联网 发布:数控铣床软件与编程 编辑:程序博客网 时间:2024/05/16 06:36
Description
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.
Input
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).
Output
For each question output the answer to it — the k-th number in sorted a[i…j] segment.
Solution
大意就是给定一些数字和m个操作,求给定区间的第k小。可持久化线段树的入门题吧,感觉还是很奇妙的。
如果没有区间的限制,那么就是建一个离散化之后的值域线段树,每个节点记录当前节点区间的数字数量,然后统计就行了
对于加上区间后的问题一个想法就是对于每次插入操作都保留一个历史版本,每次对于区间[x,y]的查询用第y棵减去第x-1棵。鱿鱼每次的修改最多影响logn个节点,我们只更改这logn个就行了。
这里离散用了unique+lower_bound的做法,的确很精简
Code
#include <stdio.h>#include <string.h>#include <algorithm>#define rep(i,st,ed) for (int i=st;i<=ed;++i)#define N 105005struct treeNode{int l,r,c;}t[N*20];int rank[N],a[N],b[N];int root[N],cnt=0;int n,m;void read(int &x) { x=0; int v=1; char ch=getchar(); for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar()); for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar()); x=x*v;}int query(int now,int pre,int l,int r,int k) { if (l==r) return l; int mid=(l+r)>>1,c=t[t[now].l].c-t[t[pre].l].c; if (c>=k) return query(t[now].l,t[pre].l,l,mid,k); else return query(t[now].r,t[pre].r,mid+1,r,k-c);}void modify(int &now,int pre,int l,int r,int pos) { now=++cnt; t[now]=(treeNode){t[pre].l,t[pre].r,t[pre].c+1}; if (l==r) return ; int mid=(l+r)>>1; if (pos<=mid) modify(t[now].l,t[pre].l,l,mid,pos); else modify(t[now].r,t[pre].r,mid+1,r,pos);}void build(int &now,int l,int r) { now=++cnt; t[now]=(treeNode){0,0,0}; if (l==r) return ; int mid=(l+r)>>1; build(t[now].l,l,mid); build(t[now].r,mid+1,r);}int main(void) { read(n); read(m); rep(i,1,n) { read(a[i]),b[i]=a[i]; } std:: sort(b+1,b+n+1); int size=std:: unique(b+1,b+n+1)-b-1; rep(i,1,n) { rank[i]=std:: lower_bound(b+1,b+size+1,a[i])-b; } build(root[0],1,n); rep(i,1,n) modify(root[i],root[i-1],1,n,rank[i]); rep(i,1,m) { int x,y,k; read(x); read(y); read(k); printf("%d\n",b[query(root[y],root[x-1],1,n,k)]); } return 0;}
- poj2104 K-th Number 离散+可持久化线段树
- 【POJ2104】K-th Number-主席树(可持久化线段树)+离散化
- POJ2104-K-th Number-区间第k大-可持久化线段树/主席树
- POJ 2104 K-th Number (可持久化线段树)
- [poj]-2104-K-th Number-可持久化线段树
- poj 2104 K-th Number 可持久化线段树
- POJ 2104 K-th Number(可持久化线段树)
- POJ 2104 K-th Number 可持久化线段树
- [POJ2104]K-th Number(主席树+讲解+可持久化基础)
- 【POJ2104】K-th Number 主席树?函数式线段树?可持久化线段树?……反正是其中一个
- poj2104 K-th Number (线段树实现)
- POJ2104 K-th Number 【线段树+二分】
- 区间第k小 poj2104 可持久化线段树
- poj-2104 K-th Number[主席树/函数式线段树/可持久化线段树]
- POJ 2104 K-th Number 区间第K大,可持久化线段树
- POJ 2104K-th Number(可持久化线段树-求第K大)
- 主席树(可持久化线段树)讲解 [POJ 2104] K-th Number
- poj2104 K-th Number (函数式线段树)
- 第十七章经典抽象数据结构四:树的前中后序遍历
- 「NOIP2017」列队 //线段树
- 【Scikit-Learn 中文文档】模型选择:选择估计量及其参数
- 浅谈时间复杂度和空间复杂度
- 如何将文件隐藏在图片中
- poj2104 K-th Number 离散+可持久化线段树
- 迭代器失效问题及迭代器的应用
- 【加密】各种加密(打乱)语言代码的sdk代码
- 【Scikit-Learn 中文文档】无监督学习: 寻求数据表示
- 网站部署nginx--uwsgi
- 汇编语言3
- 机器学习总结(四)——随机森林与GBDT(梯度提升决策树)
- 约束最优化方法之最优性条件
- 真正的轻量级WebService框架——使用JAX-WS(JWS)发布WebService