主席树/可持久化线段树总结
来源:互联网 发布:多店铺管理系统 源码 编辑:程序博客网 时间:2024/05/21 10:32
【介绍】
主席树也就是函数式线段树,运用了可持久化思想从而可以在短时间寻找到一段区间的K大值,是一个非常优秀的算法,但是属于离线算法。
【思想】
对于给定的一个序列,每次询问某一段自区间的K大值。对于这类题型,就是主席树登场的时候,首先对这个序列离散,假设去重后有x个元素,那么用线段树来维护区间中数的个数。对于询问的某一段区间[L,R],利用容斥思想,用R的前缀减去L的前缀便是答案。所以要分别对序列0~k(
进一步可以发现,其实构造好
这样可以实现可持久化,降低了空间乃至时间复杂度。
对于数组的大小也就是log2(N)*N(N表示元素个数,因为线段树的深度最多也就是log2(N))。
【核心代码】
struct PT{ PT* son[2]; int l,r,s;}tem[maxm],*Null=tem,*len=Null,*ro[maxn];void Pushup(PT* k) {k->s=k->son[0]->s+k->son[1]->s;}PT* New(int L,int R,int p)//构造新节点 { ++len; len->l=L; len->r=R; len->s=p; len->son[0]=len->son[1]=Null; return len;}PT* Build(int L,int R)//建树 { PT* now=New(L,R,0); if (L==R) return now; int mid=(R-L>>1)+L; now->son[0]=Build(L,mid); now->son[1]=Build(mid+1,R); Pushup(now); return now;}PT* Insert(PT* k,int where)//插入 { int L=k->l,R=k->r; PT* now=New(L,R,k->s); now->son[0]=k->son[0]; now->son[1]=k->son[1]; if (L==R) {now->s++; return now;} int mid=(R-L>>1)+L; if (where<=mid) now->son[0]=Insert(now->son[0],where); else now->son[1]=Insert(now->son[1],where); Pushup(now); return now;}int Query(PT* L,PT* R,int k)//询问K大值,类似平衡树思想 { if (L->l==L->r) return b[L->l]; int p=R->son[0]->s-L->son[0]->s;//容斥思想 if (p>=k) return Query(L->son[0],R->son[0],k); else return Query(L->son[1],R->son[1],k-p);}
阅读全文
0 0
- 主席树/可持久化线段树总结
- spoj3267 D-query 主席树(可持久化线段树)
- 可持久化线段树(主席树)
- 主席树(可持久化线段树)入门专题
- 主席树(可持久化线段树)学习笔记
- 【可持久化线段树】【主席树】[HDU4417]Super Mario
- 主席树(可持久化线段树)
- [BZOJ2653] middle - 主席树(可持久化线段树) - 二分
- 主席树(可持久化线段树)学习笔记
- 可持久化线段树——主席树
- hdu2665主席树(可持久化线段树)
- 【模板】可持久化线段树 1(主席树)
- 可持久化线段树(主席树)【数组】
- 【模板】可持久化线段树(主席树)
- 可持久化线段树(主席树)
- 主席树/函数式线段树/可持久化线段树 学习指南
- 主席树/函数式线段树/可持久化线段树
- poj-2104 K-th Number[主席树/函数式线段树/可持久化线段树]
- 2换行标题分割线
- echarts图表
- 【洛谷2245】星际导航
- 05.10 glusterFS分布式存储
- Linux基础之VMware下CentOS 7.3的安装
- 主席树/可持久化线段树总结
- 例4.7 简单派生类的构造函数和析构函数的执行顺序
- bzoj 1367: [Baltic2004]sequence
- 3左右居中对齐
- jstl标签库 c:foreach的使用
- JavaWeb学习-1 Tomcat安装与配置
- 代理服务器基本认识
- shell进度条
- 4文本元素