可持久化线段树
主席树,即 可持久化线段树。
可持久化:可以找到每次修改时的线段树,即 保存了线段树各个历史版本 ,这样就可以快速查询到第 i 次修改前线段树的状态。
核心思想:与历史版本的线段树共用部分结点。
很明显每次新建一棵线段树带来的时空消耗是难以承受的,但是可以发现,每次单点修改时,只会变动logN个结点(即从根结点到对应叶结点的路径),所以剩下的结点都可以和前一个版本的线段树共用。(所以要每次采用动态创建logN个结点,且可以发现每个版本的根结点一定不同)
若 M次修改,空间复杂度为O( 4N + M*logN )(4N为初始版本线段树大小)
具体操作(以维护区间和为例):
建树:
即建立 初始版本的线段树,注意,即使一开始为空树,也必须要建立(令值全为0),因为修改操作必须存在前一个版本的树。
int root[maxn]; //root[i]:第i个版本线段树的根结点
int t[maxn<<5],ls[maxn<<5],rs[maxn<<5],cnt=0; //结点,左子树,右子树,注意空间要开足够大
int build(int l,int r)
{
int rt=++cnt;
if