我们先离散化,然后根据权值建立线段树,假设我们现在有一颗权值线段树,表示在区间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. tweenjs缓动算法使用小实例

    这里的tweenjs不是依托于createjs的tewwnjs,而是一系列缓动算法集合.因为本身是算法,可以用在各个业务场景中,这也正是总结学习它的价值所在.tweenjs代码详情: /* * Twe ...

  2. Jedis源码解析——Jedis和BinaryJedis

    1.基本信息 先来看看他们的类定义: public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands ...

  3. js获取某周、某月、下月、某季度的开始日期、结束日期及判断日期第几周

    //格式化日期:yyyy-MM-dd function formatDate(date) {   var myyear = date.getFullYear();   var mymonth = da ...

  4. C/S结构 B/S结构

    [1]C/S 结构,即大家熟知的客户机和服务器结构.它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销.目前大多数应 ...

  5. thinkPHP框架单一入口文件解析

    一.index.php  (可参考ThinkPHP学习手册http://document.thinkphp.cn/manual_3_2.html#entrance_file) index.php单入口 ...

  6. Java经典设计模式 总览

    一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥 ...

  7. [计算机网络-应用层] DNS:因特网的目录服务

    我们知道有两种方式可以识别主机:通过主机名或者IP地址.人们喜欢便于记忆的主机名标识,而路由器则喜欢定长的.有着层次结构的IP地址.为了折中这些不同的偏好,我们需要一种能进行主机名到IP地址转换的目录 ...

  8. 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询

    题目描述 “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. ...

  9. 【bzoj1708】[USACO2007 Oct]Money奶牛的硬币 背包dp

    题目描述 在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币系统中,硬币的面值通常是1,5,10,20或25,50,以及100单位的 ...

  10. [洛谷P4550]收集邮票

    题目大意:有$n(n\leqslant10^4)$个物品,第$i$次会从这$n$个物品中随机获得一个,并付出$i$的代价,问获得所有的$n$个物品的代价的期望. 题解:令$f_i$表示现在已经获得了$ ...