我们先离散化,然后根据权值建立线段树,假设我们现在有一颗权值线段树,表示在区间1-n中每个数出现了几次,那么我们可以二分的求出来这个区间的k大值,类似sbt的select操作,那么因为点的权值插入是无序的,所以我们并不能对于子区间l,r做上述操作,因为我们无法提出这个区间,那么我们建立可持久化线段树就好了。

  反思:第一次写可持久化数据结构,自己yy着写的,开始没注意到新建节点的时候节点的值就应该是上一棵线段树中该节点对应节点的值+1,而是维护的这个值,就导致了各种重复计算问题= =。

  

//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010 using namespace std; struct segment {
int left,right,sum;
int son[];
segment(){
left=right=sum=;
memset(son,,sizeof son);
}
}t[maxn<<]; struct rec {
int num,key;
}a[maxn]; int n,m,tot;
int rot[maxn],ans[maxn]; bool cmp1(rec x,rec y) {
return x.key<y.key;
} bool cmp2(rec x,rec y) {
return x.num<y.num;
} void build(int &x,int l,int r) {
if (!x) x=++tot;
t[x].left=l; t[x].right=r;
if (l==r) return ;
int mid=t[x].left+t[x].right>>;
build(t[x].son[],l,mid); build(t[x].son[],mid+,r);
} void insert(int &x,int rot,int y,int l,int r) {
if (!x) x=++tot;
t[x].left=l; t[x].right=r;
if (l==r) {
t[x].sum=t[rot].sum+; return ;
}
int mid=t[x].left+t[x].right>>;
if (y>mid) {
insert(t[x].son[],t[rot].son[],y,mid+,r);
t[x].son[]=t[rot].son[];
//t[t[x].son[0]].sum=t[t[t[x].son[0]].son[0]].sum+t[t[t[x].son[0]].son[1]].sum;
} else {
insert(t[x].son[],t[rot].son[],y,l,mid);
t[x].son[]=t[rot].son[];
//t[t[x].son[1]].sum=t[t[t[x].son[1]].son[0]].sum+t[t[t[x].son[1]].son[1]].sum;
}
t[x].sum=t[rot].sum+;
} int ask(int lx,int rx,int k) {
//printf("|%d %d %d\n",lx,rx,k);
if (t[lx].left==t[lx].right) return t[lx].left;
if (k>t[t[rx].son[]].sum-t[t[lx].son[]].sum)
return ask(t[lx].son[],t[rx].son[],k-t[t[rx].son[]].sum+t[t[lx].son[]].sum); else
return ask(t[lx].son[],t[rx].son[],k);
} int main() {
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i].key),a[i].num=i;
sort(a+,a++n,cmp1);
int j=; ans[]=a[].key;
for (int i=,cur=a[].key;i<=n;i++)
if (a[i].key==cur) a[i].key=j; else cur=a[i].key,a[i].key=++j,ans[j]=cur;
//for (int i=1;i<=n;i++) printf("%d %d\n",a[i].num,a[i].key);
sort(a+,a++n,cmp2);
build(rot[],,j);
for (int i=;i<=n;i++) insert(rot[i],rot[i-],a[i].key,,j);
//for (int i=1;i<=tot;i++) printf("%d %d %d %d %d %d\n",i,t[i].son[0],t[i].son[1],t[i].left,t[i].right,t[i].sum);
for (int i=;i<=m;i++) {
int l,r,k; scanf("%d%d%d",&l,&r,&k);
printf("%d\n",ans[ask(rot[l-],rot[r],k)]);
}
//for (int i=1;i<=j;i++) printf("%d ",ans[i]); printf("\n");
//for (int i=1;i<=n;i++) printf("%d ",a[i].key); printf("\n");
return ;
}

poj 2104 可持久化线段树的更多相关文章

  1. 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 ...

  2. POJ 2104 K-th Number (可持久化线段树)

    题目大意 给一个长度为n的序列,有m个询问,每次询问一个区间里面第k小的数. 解题分析 静态的区间第k大.复习了一下可持久化线段树. 首先对数值离散化,建一颗权值线段树.按照序列的顺序依次插入,每一个 ...

  3. K-th Number 【POJ - 2104】【可持久化线段树】

    题目链接 因为这道题没有删除修改之类的,所以很多人会用离散化之后的线段树来做,但是实际上(可能是我懒得去做离散化这个操作了),然后就是直接写可持久化线段树,区间的长度就是int的从最小到最大的长度,然 ...

  4. POJ- 2104 hdu 2665 (区间第k小 可持久化线段树)

    可持久化线段树 也叫函数式线段树也叫主席树,其主要思想是充分利用历史信息,共用空间 http://blog.sina.com.cn/s/blog_4a0c4e5d0101c8fr.html 这个博客总 ...

  5. poj 2104 K-th Number 主席树+超级详细解释

    poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...

  6. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  7. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  8. 【BZOJ-2653】middle 可持久化线段树 + 二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1298  Solved: 734[Submit][Status][Discu ...

  9. HDU 4866 Shooting(持久化线段树)

    view code//第二道持久化线段树,照着别人的代码慢慢敲,还是有点不理解 #include <iostream> #include <cstdio> #include & ...

随机推荐

  1. js实现倒计时60秒的简单代码

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  2. nginx的平滑升级,不间断服务

    nginx的平滑升级,不间断服务   Nginx更新真的很快,最近nginx的1.0.5稳定版,nginx的0.8.55和nginx的0.7.69旧的稳定版本已经发布.我一项比较喜欢使用新版本的软件, ...

  3. MAC锁屏不断网(快捷键启用屏保)

    第一步:要设定锁定输入密码的设置,进入'系统偏好设置''安全性与隐私',将选项'进入睡眠或开始屏幕保护程序后'打勾,选'立即'. 第二步:到'launchpad'中的'其他'文件夹打开'Automat ...

  4. DELPHI dbgrid 选中的是第几行 怎么判断?

    使用DataSource.DataSet.RecNo可以得到dbgrid选中的是第几行,示例代码如下: procedure TForm1.btn1Click(Sender: TObject); beg ...

  5. BZOJ 1821 部落划分(二分+并查集)

    答案是具有单调性的. 因为最近的两个部落的距离为mid,所以要是有两个野人的距离<mid,则他们一定是一个部落的. 用并查集维护各联通块,如果最后的联通块个数>=k,那么mid还可以再小点 ...

  6. OpenStack Queens版本Horizon定制化开发

    工具环境 1.VMware workstation 12+: 2.Ubuntu系统+Linux Pycharm: 3.OpenStack Queens版本Horizon代码: 问题及解决 1.项目代码 ...

  7. windows 架设SVN服务器

    想完整走一遍svn布置及使用流程,试完整理了一下: step 1:下载安装 1.安装SVN服务器,到http://subversion.apache.org/packages.html 上下载wind ...

  8. Python对文件和文件夹的高级操作模块shutil

    shutil模块提供了许多关于文件和文件夹的高级操作. 特别提供了支持文件复制和删除的功能. # 将文件对象fsrc的内容复制到文件类对象fdst.length(可选参数)是缓冲区大小 shutil. ...

  9. python 深浅copy的例子

    1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.2. copy.deepcopy 深拷贝 拷贝对象及其子对象一个很好的例子:import copya = [1, 2, 3, ...

  10. CF17E:Palisection——题解

    https://vjudge.net/problem/CodeForces-17E http://codeforces.com/problemset/problem/17/E 题目大意:给一个长度为n ...