我们先离散化,然后根据权值建立线段树,假设我们现在有一颗权值线段树,表示在区间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. C#中堆和栈的区别?

    http://www.jb51.net/article/55306.htm http://www.cnblogs.com/JimmyZhang/archive/2008/01/31/1059383.h ...

  2. 3dContactPointAnnotationTool开发日志(十六)

      调了一上午才发现是把下面这个函数: private float DivideTriangle(int []triangle,out int []outTriangle,List<Vector ...

  3. 【week2】四人小组项目(WBS、NABCD)

    项目选题:东北师范大学论坛 小组名称:nice! 项目组长:李权 组员:于淼 刘芳芳 杨柳 本周任务:要求给出需求概述.功能列表.痛点或亮点.NABCD及WBS模型在此项目中的应用. 作为东北师范大学 ...

  4. 安装django 提示ImportError: No module named setuptools

    安装django前要先安装setuptools 先安装一些必要的包,否则会报错:Python build finished, but the necessary bits to build these ...

  5. Struts2自定义结果视图(servlet验证码)

    1.编写一个类实现com.opensymphony.xwork2.Result,或者继承org.apache.struts2.dispatcher.StrutsResultSupport 2.自定义的 ...

  6. JAVA开发工作流程

    阶段 0 :拟出一个计划 决定在后面的过程中采取哪些步骤,思考整个开发任务如何实现,分步骤建立“路标”,这样可以帮助自己开发时一步一个脚印的逐步完成,有效的防止自己在开发过程中迷失方向. 阶段 1 : ...

  7. Codeforces Round #522 Div. 1 没打记

    开场被A劝退,写了得有50min于是不敢交了.unrated了喜闻乐见. A:瞎猜都能猜到如果要走到那条直线上,进入直线的点横坐标或纵坐标与起点相同,离开直线的点横坐标或纵坐标与终点相同,证明脑补一下 ...

  8. Andorid API Package ---> android

    包名: android                                                        Added in API level 1  URL:http:// ...

  9. [ZJOI2010]贪吃的老鼠 网络流

    ---题面--- 题解: 这是一道强题emmmm,做法非常巧妙,,,我也是看了好久大佬题解才看明白一点 首先考虑没有限制的情况,即n个老鼠可以在同一时刻吃同一块奶酪 对各个时间段拆点,连奶酪 ---& ...

  10. BZOJ1486:[HNOI2009]最小圈——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1486 https://www.luogu.org/problemnew/show/P3199 题面 ...