【洛谷3834】 【模板】可持久化线段树 (主席树)
来源:互联网 发布:搭建局域网网络硬盘 编辑:程序博客网 时间:2024/05/17 23:45
题面
具体题目不再叙述,参考洛谷
题目大意,求区间[l,r]中第k大的数
题解
主席树很经典的运用
首先将值离散化之后,构建一颗值域线段树
储存区间和
0版本的线段树是空树
每次在值域上增加1就重构一颗线段树
很显然,任意两颗相邻线段树的值得和差为1
而相同的区间内要么相等要么多1
那么,我们也很容易的可以推出,区间第k大可以通过第r版本和第(l-1)版本的线段树算出来
每次计算左儿子
如果r的左儿子已经比(l-1)的左儿子多出来的和大于k
那么在左儿子查找k大值
否则则在右儿子上查找第(k-val)大值,其中,val是和的差
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<queue>#include<map>#include<vector>#include<algorithm>using namespace std;#define MAXN 10000000#define MAX 500000inline int read(){ register int x=0,t=1; register char ch=getchar(); while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-'){t=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();} return x*t;}struct Node{ int ch[2]; int l,r; int val;}c[MAXN];int N,M,a[MAX],b[MAX],NN,mm[MAX];int cnt,Root[MAX];map<int,int> MM;void build(int now,int l,int r){ ++cnt;c[now].l=l;c[now].r=r; if(l==r)return; int mid=(l+r)>>1; c[now].ch[0]=cnt+1; build(cnt+1,l,mid); c[now].ch[1]=cnt+1; build(cnt+1,mid+1,r);}void update(int now,int k,int x){ ++cnt;//int tt=cnt; c[cnt]=c[now];c[cnt].val+=x; int l=c[now].l,r=c[now].r; if(l==r)return; int mid=(l+r)>>1; if(k<=mid){c[cnt].ch[0]=cnt+1;update(c[now].ch[0],k,x);} else {c[cnt].ch[1]=cnt+1;update(c[now].ch[1],k,x);}}int Query(int now1,int now2,int k){ if(c[now1].l==c[now1].r)return c[now1].l; int rr=c[c[now2].ch[0]].val-c[c[now1].ch[0]].val; if(rr<k)return Query(c[now1].ch[1],c[now2].ch[1],k-rr); else return Query(c[now1].ch[0],c[now2].ch[0],k);}int main(){ N=read();M=read(); for(int i=1;i<=N;++i)a[i]=b[i]=read(); sort(&b[1],&b[N+1]); NN=unique(&b[1],&b[N+1])-b-1; for(int i=1;i<=NN;++i)MM[b[i]]=i; for(int i=1;i<=NN;++i)mm[i]=b[i]; for(int i=1;i<=N;++i)a[i]=MM[a[i]]; Root[0]=1;build(1,1,NN); for(int i=1;i<=N;++i){Root[i]=cnt+1;update(Root[i-1],a[i],1);} for(int i=1;i<=M;++i) { int u=read(),v=read(),w=read(); int ans=Query(Root[u-1],Root[v],w); printf("%d\n",mm[ans]); } return 0;}
阅读全文
0 0
- 【模板】可持久化线段树 1(主席树)
- 【模板】可持久化线段树(主席树)
- 【洛谷3834】 【模板】可持久化线段树 (主席树)
- luoguP3834 【模板】可持久化线段树 1(主席树)
- 可持久化线段树(主席树)
- 主席树(可持久化线段树)入门专题
- 主席树(可持久化线段树)学习笔记
- 主席树(可持久化线段树)
- hdu2665主席树(可持久化线段树)
- 可持久化线段树(主席树)【数组】
- 可持久化线段树(主席树)
- 【模板】主席树/函数式线段树/可持久化线段树
- 主席树/可持久化线段树简介(洛谷P3834/P3919)
- spoj3267 D-query 主席树(可持久化线段树)
- 【可持久化线段树】【主席树】[HDU4417]Super Mario
- [BZOJ2653] middle - 主席树(可持久化线段树) - 二分
- 主席树(可持久化线段树)学习笔记
- 主席树/可持久化线段树总结
- 数据结构之树
- 1621: [Usaco2008 Open]Roads Around The Farm分岔路口(记忆化搜索)
- Cookie与Session的区别
- 值传递引用传递(java)
- #coding=utf-8的作用 还是乱码
- 【洛谷3834】 【模板】可持久化线段树 (主席树)
- /etc/profile,/etc/bashrc,~/.bash_profile,~/.bashrc,~/.bash_logout的区别
- js复习笔记day7
- HDU
- 数据包络分析法(DEA)在数学建模中的应用
- canvas标签的用法
- 排列和组合简单的递归思路以及C++实现
- PAT A 1095. Cars on Campus (30)
- vue 绑定单值和双向绑定