zoukankan      html  css  js  c++  java
  • 【可持久化数据结构】主席树(可持久化线段树)

    在学习数据结构的路上渐行渐远。。。
    学习了主席树(可持久化线段树)/(函数式线段树)。
    简单的介绍一下可持久化数据结构的意思,大概就是可以保存历史版本的数据结构。
    对于线段树而言,其的可持久化就是对每次操作建立不同版本的线段树,但显然,这样的时空复杂度过大,是不可接受的。
    考虑只有单点修改的情况,一次操作影响的部分不过只有一条链,故可以只对这部分建立新版本,这大概就是可持久化线段树的基本思想。
    对于查询,只需要使用不同版本的根进行查询即可,与线段树没有特别大的差别。
    每次修改与查询的时间复杂度均为(O(n log_{2} n))
    显然,每次修改只会影响 (O(log_{2}n))个线段树上的点,故每次修改只会新建立(O(log_{2} n ))个点,空间复杂度为(O(n log_{2} n))
    接下来就是如何新建点的问题,只需要动态开点,其中一个孩子仍为旧版本的点,新修改的链上点则为新建点即可。
    例题为POJ 2104 / POJ 2761 / luogu 3834
    模板如下:

    #include <stdio.h>
    #include <algorithm>
    #define mid (l+r>>1)
    #define MN 100005
    #define MM (((1<<17)*17)<<1)
    #define R register
    inline int read(){
    	R int x; R char c; R bool f;
    	for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
    	for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0');
    	return f?-x:x;
    }
    int ls[MM],rs[MM],v[MM],cnt,rt[MN],val[MN],rk[MN],vrk[MN],n,m;
    inline bool cmp(int a,int b){return val[a]<val[b];}
    inline int copy(int old){ls[++cnt]=ls[old],rs[cnt]=rs[old],v[cnt]=v[old];return cnt;}
    void modify(int val,int &x,int l,int r){
    	x=copy(x);++v[x];if (l==r) return;
    	if (val<=mid) modify(val,ls[x],l,mid);
    	else modify(val,rs[x],mid+1,r);
    }
    int query(int rk,int lq,int rq,int l,int r){
    	if (l==r) return l;R int tmp=v[ls[rq]]-v[ls[lq]];
    	if (rk<=tmp) return query(rk,ls[lq],ls[rq],l,mid);
    	else return query(rk-tmp,rs[lq],rs[rq],mid+1,r);
    }
    int main(){
    	n=read(),m=read();
    	for (R int i=1; i<=n; ++i)
    		val[i]=read(),rk[i]=i;
    	std::sort(rk+1,rk+n+1,cmp);
    	for (R int i=1; i<=n; ++i) vrk[rk[i]]=i;
    	for (R int i=1; i<=n; ++i)
    		rt[i]=rt[i-1],modify(vrk[i],rt[i],1,n);
    	for (R int i=1; i<=m; ++i){
    		R int l=read(),r=read(),k=read();
    		printf("%d
    ",val[rk[query(k,rt[l-1],rt[r],1,n)]]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    解决undefined reference to `__poll_chk@GLIBC_2.16' 错误
    交叉编译总结 libosscore.a libcurl.a libmysqlclient.a
    APUE环境配置
    UDT中epoll对CLOSE状态的处理
    查看ld搜索路径
    linux shell 比较文件夹内容 diff
    交互式makefile
    linux shell取文本最后一行
    linux 查看静态库,动态库是32位还是64位
    python学习day4之路
  • 原文地址:https://www.cnblogs.com/Melacau/p/president_segment_tree.html
Copyright © 2011-2022 走看看