P5055 【模板】可持久化文艺平衡树 题解
Description
Solution
顾名思义,我们要实现的就是可持久化文艺平衡树,也就是带修的文艺平衡树。
前置知识:文艺平衡树,可持久化平衡树
对于每次修改,我们要新建出被修改的那棵子树,所有的修改及查询操作全都是在要求的版本中进行。
修改之后建出新的版本。
我写的时候直接令 ( 是输入的要求在 上面进行操作),然后把 传到函数里即可。
思路大概就是这样吧。
我用 实现的。
注意:插入的
split
时,要split(pos)
而不是split(val)
!!!我因为这个卡了一晚上!!!!(可能是我太傻了)
Code
( split
和 pushdown
的过程中要新建节点,各种操作中传入 root
的地址便可以像普通的 一样写啦,具体见下面代码)
#include <bits/stdc++.h>
#define ll long long
#define ls(x) t[x].l
#define rs(x) t[x].r
using namespace std;
namespace IO{
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
template <typename T> inline void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
}
}
using namespace IO;
const int N = 2e5 + 10;
int n;
ll lst;
struct fhq_treap{
int val, siz, wei, l, r;
ll sum;
bool rev;
}t[N << 6];
int rt[N], tot;
inline int clone(int y){
int x = ++tot;
return t[x] = t[y], tot;
}
inline void pushup(int x){
t[x].siz = t[ls(x)].siz + t[rs(x)].siz + 1;
t[x].sum = t[ls(x)].sum + t[rs(x)].sum + t[x].val;
}
inline void pushdown(int x){
if(t[x].rev){
swap(ls(x), rs(x));
if(ls(x)) t[x].l = clone(t[x].l), t[t[x].l].rev ^= 1;
if(rs(x)) t[x].r = clone(t[x].r), t[t[x].r].rev ^= 1;
t[x].rev = 0;
}
}
inline void split(int x, int k, int &a, int &b){
if(!x) return a = b = 0, void();
pushdown(x);
if(k >= t[ls(x)].siz + 1){
a = clone(x);
split(rs(x), k - t[ls(x)].siz - 1, rs(a), b);
pushup(a);
}
else{
b = clone(x);
split(ls(x), k, a, ls(b));
pushup(b);
}
}
inline int merge(int x, int y){
if(!x || !y) return x | y;
if(t[x].wei <= t[y].wei){
pushdown(x);
rs(x) = merge(rs(x), y);
return pushup(x), x;
}else{
pushdown(y);
ls(y) = merge(x, ls(y));
return pushup(y), y;
}
}
inline int newnode(int k){
t[++tot].val = k, t[tot].sum = k, t[tot].siz = 1, t[tot].wei = rand();
return tot;
}
inline void insert(int &root, int p, int k){
int a, b;
split(root, p, a, b);
root = merge(merge(a, newnode(k)), b);
}
inline void remove(int &root, int k){
int a, b, c;
split(root, k, a, b);
split(a, k - 1, a, c);
root = merge(a, b);
}
inline void reverse(int &root, int l, int r){
int a, b, c;
split(root, r, a, c);
split(a, l - 1, a, b);
t[b].rev ^= 1;
root = merge(merge(a, b), c);
}
inline ll query(int &root, int l, int r){
int a, b, c;
split(root, r, a, c);
split(a, l - 1, a, b);
ll res = t[b].sum;
root = merge(merge(a, b), c);
return res;
}
int main(){
n = read();
for(int i = 1; i <= n; ++i){
int u = read(), op = read();
rt[i] = rt[u];
if(op == 1){
int p = read() ^ lst, x = read() ^ lst;
insert(rt[i], p, x);
}else if(op == 2) remove(rt[i], read() ^ lst);
else if(op == 3){
int l = read() ^ lst, r = read() ^ lst;
reverse(rt[i], l, r);
}else{
int l = read() ^ lst, r = read() ^ lst;
write(lst = query(rt[i], l, r)), puts("");
}
}
return 0;
}
本文作者:xixike
本文链接:https://www.cnblogs.com/xixike/p/15736003.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 用 DeepSeek 给对象做个网站,她一定感动坏了
· DeepSeek+PageAssist实现本地大模型联网
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· 从 14 秒到 1 秒:MySQL DDL 性能优化实战