【数据结构】可持久化线段树&Trie总结

本文介绍了可持久化数据结构的概念,重点讲解了可持久化线段树和Trie在处理区间查询和历史版本访问中的应用。通过具体的例题分析,阐述了如何利用这些数据结构解决区间第k大问题和树形问题,同时提供了实现思路和模板。
摘要由CSDN通过智能技术生成

可持久化:

可以访问历史版本的“升级版”的数据结构,利用访问历史版本的性质,可以做到许多在区间上的操作。

可持久化线段树:

例题:
cqoi2111:区间第k大

给定一个长度为n的序列,m个询问,每个询问的形式为:l,r,k表示在[l,r]间中的第k大元素.
(n<=100000, m<=100000,1<=l<=r<=n, 1<=k<=r-l+1)

如果用线段树来储存某个区间的第i大,显然是很不好实现的。因此,我们换一个思路,我们将线段树建在值域上(需要离散化),储存某个区间存在多少个数。
每插入一个新的值,那么这个值会影响线段树上的哪些节点?
这里写图片描述
这里写图片描述
这样一来,我们就做到了保存历史版本。
具体实现,我们可以再插入新节点时,插入位置以外的半个区间的指针指向上一个版本,继续走当前这个区间,直到抵达叶节点为止。
对于这道题,求解的过程很类似于在平衡树上找第k大
如果左区间的数的个数>k,走左树
反之,走右树,并将 k-左区间的数的个数

附上我的(丑)模板

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
struct node{
    int cnt;
    node *ch[2];
}Seg[MAXN*20],*root[MAXN],*ncnt=Seg;
int a[MAXN],b[MAXN],bn,n,m;
void init(node *p){
    p->cnt=0;
    p->ch[0]=p->ch[1]=NULL;
}
void build(node *&p,int l,int r){
    p=++ncnt;
    init(p);
    if(l+1>=r)
        return ;
    int mid=(l+r)>>1;
    build(p->ch[0],l,mid);
    build(p->ch[1],mid,r);
}
void insert(node *&x,node 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值