线段树 plus 总结
线段树合并,可持久化,分裂的总结,没有什么知识性的东西,只是根据自己的问题整理了一些注意事项。
线段树合并
注意事项
- 这时候空间就比较大了,不要一来就
#define int long long。
然后有一些卡空间的方法。
- 线段树合并时不要新开一个点,直接合并到其中的一棵树上去。
int merge(int pa,int pb,int L,int R){
if(!pa||!pb)return pa+pb;
int now=++idx;
if(L==R){
f[now].cnt=f[pa].cnt+f[pb].cnt;
f[now].sum=L;
return now;
}
int mid=L+R>>1;
f[now].l=merge(f[pa].l,f[pb].l,L,mid);
f[now].r=merge(f[pa].r,f[pb].r,mid+1,R);
pushup(now);
return now;
}
上面这种写法会新开一倍的点。
改也是只需要改几个字母就行了。
int merge(int pa,int pb,int L,int R){
if(!pa||!pb)return pa+pb;
int now=pa;//合并到其中一棵树上去。
if(L==R){
f[now].cnt=f[pa].cnt+f[pb].cnt;
f[now].sum=L;
return now;
}
int mid=L+R>>1;
f[now].l=merge(f[pa].l,f[pb].l,L,mid);
f[now].r=merge(f[pa].r,f[pb].r,mid+1,R);
pushup(now);
return now;
}
- 捡前面丢掉的垃圾。
合并之后,其中一棵树的节点就不需要了,但是也不能让它们空着,可以记录这些不要的点,给后面新加的点用。
这时候就需要一边合并一边加点了。
可持久化
不是我说白了这不是随便切吗
link
关于空间
每次修改新增一条链,也就是 \(\log V\) 个点,所以空间记得开 \(O(n\log V)\)。
应用
可持久化的本质就是对线段树作前缀和,所以可以用维护前缀和的数据结构维护(树套树),也可以差分来维护原数组(差分数组的前缀和是原数组)。
树套树
\(\large空间是 O(n\log^2 n)!\)
\(\Large空间是 O(n\log^2 n)!\)
\(\LARGE空间是 O(n\log^2 n)!\)
关于题目
线段树分裂
- 记得要引用。
- 然后就是要分清楚传进去的参数那个是被分裂的,哪个是分裂出来的。
浙公网安备 33010602011771号