正题

评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P3834


题意

给定一个长度为n的序列,有m个询问,求一个区间内的第k小的树。


解题思路

我们先思考用线段树快速询问第k小的树
我们可以用权值线段树来处理第k小的树,先将数组离散化(排序加去重),然后下标[l...r][l...r][l...r]表示在离散化序列内l∼rl∼rl\sim r中的数出现过多少次,然后因为已经离散化了所以我们可以直接根据两个子节点返回的值来进行向下寻找。
我们开始考虑区间问题。区间问题就是只算上这个区间内的数的线段树,我们可以使用前缀和。建立n个线段树表示1∼x1∼x1\sim x这个区间,然后每次查询就是用第rrr棵线段树减去·第l−1" role="presentation">l−1l−1l-1棵线段树就好了。
但是这么一算其实时间复杂度和空间复杂度还不如暴力那就直接暴力吧。这么一想我们会发现其实每次修改都只修改一条链,那么我们为什么不每次只增加一条链呢?
那么我们开始今天的正题:可持久化线段树(主席树)。
直接给出结构

(上面的数是区间范围,下面的是值。绿色为新增加的点)
我们每次只修改一条链,然后没有修改的那一部分和原来的节点相连,每次询问不同版本时只需要从不同版本的根节点开始访问就可以了。而这样我们就需要动态开点了。


代码

#include<cstdio>
#include<algorithm>
#define MN 200010
using namespace std;
struct tnode{int w,l,r,ls,rs;
}t[MN<<5];
int n,m,x,y,k,a[MN],b[MN],root[MN],num,q,w;
int build(int l,int r)//建立一棵空树
{int k=++num;t[k].l=l,t[k].r=r;if (l==r) return k;int mid=(l+r)>>1;t[k].ls=build(l,mid);t[k].rs=build(mid+1,r);//左右分区return k;//返回编号
}
int addt(int k,int z)//建立一条新链
{int nb=++num;t[nb]=t[k];t[nb].w++;//动态开点if (t[k].l==z&&t[k].r==z) return nb;//到达节点int mid=(t[k].l+t[k].r)>>1;if (z<=mid) t[nb].ls=addt(t[k].ls,z);else t[nb].rs=addt(t[k].rs,z);//建立下一个节点return nb;
}
int query(int k1,int k2,int k)//前缀和询问区间
{if (t[k1].l==t[k1].r) return t[k1].l;w=t[t[k2].ls].w-t[t[k1].ls].w;//计算左子树在这个区间内的数字数量if (k<=w) return query(t[k1].ls,t[k2].ls,k);else return query(t[k1].rs,t[k2].rs,k-w);//向下询问
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];sort(b+1,b+1+n);//排序(离散化1)int q=unique(b+1,b+1+n)-b-1;//去重(离散化)root[0]=build(1,q);//建立空树for (int i=1;i<=n;i++){int te=lower_bound(b+1,b+1+q,a[i])-b;//二分寻找原来的位置root[i]=addt(root[i-1],te);//建立一条链}for (int i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&k);printf("%d\n",b[query(root[x-1],root[y],k)]);//询问区间}
}

P3834-【模板】可持久化线段树 1(主席树)相关推荐

  1. 学习笔记:可持久化线段树(主席树):静态 + 动态

    学习笔记:可持久化线段树(主席树):静态 + 动态 前置知识: 线段树.线段树分享可以看:@秦淮岸.@ZYzzz.@妄想の岚がそこに 树状数组.\(BIT\)分享可以看:@T-Sherlock.Chi ...

  2. 【洛谷】P3919 【模板】可持久化线段树(主席树)

    题目 传送门:QWQ 分析 主席树的模板,囤着 代码 #include <bits/stdc++.h> using namespace std; const int N=1000010; ...

  3. 可持久化线段树【主席树】可持久化并查集【主席树+并查集】

    笼统的主席树原理 众所周知, 主席树是可以持久化的, 换言之你能知道你所维护信息的所有历史状态. 主席树是这样做的: 1. 首先建一颗朴素的线段树,代表初始状态 (下图黑色) , 也就是第0次操作后的 ...

  4. 可持久化线段树(主席树)【舰娘系列】【自编题】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=60083619 向大(hei)佬(e)势力学(di ...

  5. 【bzoj3524】【Poi2014】【Couriers】可持久化线段树(主席树)水题

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62485671 向大(hei)佬(e)势力学(di ...

  6. SPOJ - DQUERY D-query(莫队/线段树+离线/主席树)

    题目链接:点击查看 题目大意:给出一个由n个数组成的序列,再给出m次查询,每次查询区间[l,r]中有多少个不同的数 题目分析:莫队模板题,直接套板子就好了 有点意思的是函数返回值为布尔类型,然后没有r ...

  7. 【牛客 - 157C】PH试纸(前缀和,或权值线段树,主席树)

    题干: 链接:https://ac.nowcoder.com/acm/contest/157/C 来源:牛客网 题目描述 PH试纸,是一种检测酸碱度的试纸,试纸红色为酸性,蓝色为碱性. HtBest有 ...

  8. BZOj #4771. 七彩树(主席树+dfn序+lca)

    BZOj #4771. 七彩树 description solution code description 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色, ...

  9. 2019.03.25 bzoj4539: [Hnoi2016]树(主席树+倍增)

    传送门 题意:给一棵大树,令一棵模板树与这棵树相同,然后进行mmm次操作,每次选择模板树中的一个节点aaa和大树中一个节点bbb,把aaa这棵子树接在bbb上面,节点编号顺序跟aaa中的编号顺序相同. ...

  10. 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)

    传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...

最新文章

  1. Kafka面试题及答案整理 110道 (持续更新)
  2. 关闭打开Excel弹出要安装“Microsoft.VisualStudio.QualityTools.LoadTestExcelAddIn.vsto”加载项
  3. duilib combo增加搜索栏_微信对话框上线搜一搜,搜索一步到位!
  4. mysql面试100题及答案_PHP面试100题汇总
  5. git 为什么会有多个head_继续学习Git
  6. Tomcat提示:Error starting static Resources......
  7. word中中文保持正体,英文用斜体的方法.
  8. 一些js/css动画 mark
  9. JS模块化开发_思维导图
  10. 什么是低代码(LowCode)/无代码(NoCode)平台?
  11. iis6 元数据库与iis6 配置的兼容 出错问题
  12. 印象笔记如何分享链接_【记录】试用印象笔记最新的笔记分享出页面的功能
  13. 盗墓笔记—阿里旺旺ActiveX控件imageMan.dll栈溢出漏洞研究
  14. Error: label vector and instance matrix must be double的解决方法
  15. Unmapped Spring configuration files found. Please configure Spring facet.
  16. C语言学习教程免费分享
  17. 如何计算机画函数图形,Excel中怎么绘制出好看的函数图像
  18. 语文默写的决斗(YZOJ-1069)
  19. MySQL必知必会6
  20. Win10 无线网络802.1X认证 PEAP问题

热门文章

  1. php父子遍历,php无限分类父子追溯方法
  2. webgl坐标转换_OpenGL/WebGL顶点坐标变换过程简介
  3. python编译安装没有c扩展_为什么在安装simplejson时得到“C扩展无法编译”?
  4. hashset默认长度是多少?_看看,这些细节上的坑,你犯了多少?
  5. 常用计算机二级函数,计算机二级MS office常用函数
  6. Java项目几个月能完成_c#项目转JAVA,第5个月,基本完成
  7. vue 插入word模板 项目_10 分钟为你的 vue 项目编写代码文档
  8. setnx和expire合成一条指令_Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?...
  9. leetcode——344. 反转字符串
  10. [C++11]独占的智能指针unique_ptr的初始化和使用