洛谷P5055 可持久化文艺平衡树 (可持久化treap)
文艺平衡树的可持久化版,可以使用treap实现。
作为序列使用的treap相对splay的优点如下:
1.代码短
2.容易实现可持久化
3.边界处理方便(splay常常需要在左右两端加上保护结点以防越界,而treap一般不用)
可以分裂合并的treap一般称作无旋treap或FHQ-treap,不过我个人觉得它的结构和普通的treap没什么两样,只是多了个分裂和合并的操作而已...
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e7+,inf=0x3f3f3f3f;
int ch[N][],val[N],siz[N],rd[N],rev[N],tot,n,m,rt[N];
ll sum[N];
#define l(u) ch[u][0]
#define r(u) ch[u][1]
int newnode(int x) {int u=++tot; val[u]=sum[u]=x,siz[u]=,rd[u]=rand(),l(u)=r(u)=rev[u]=; return u;}
int cpy(int u) {int w=++tot; val[w]=val[u],sum[w]=sum[u],rd[w]=rd[u],siz[w]=siz[u],rev[w]=rev[u],l(w)=l(u),r(w)=r(u); return w;}
void pu(int u) {siz[u]=siz[l(u)]+siz[r(u)]+,sum[u]=sum[l(u)]+sum[r(u)]+val[u];}
void pd(int u) {
if(rev[u]) {
rev[u]=;
if(l(u))l(u)=cpy(l(u));
if(r(u))r(u)=cpy(r(u));
swap(l(u),r(u));
rev[l(u)]^=,rev[r(u)]^=;
}
}
void sp(int w,int k,int& u,int& v) {
if(!w) {u=v=; return;}
pd(w);
if(k>=siz[l(w)]+)u=cpy(w),sp(r(w),k-(siz[l(w)]+),r(u),v),pu(u);
else v=cpy(w),sp(l(w),k,u,l(v)),pu(v);
}
void mg(int& w,int u,int v) {
if(!u||!v) {w=u|v; return;}
if(rd[u]>rd[v])pd(u),w=u,mg(r(w),r(u),v);
else pd(v),w=v,mg(l(w),u,l(v));
pu(w);
}
void rv(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
rev[M]^=;
mg(u,L,M),mg(u,u,R);
}
void ins(int& u,int p,int x) {
int L,M,R;
sp(u,p,L,R),mg(L,L,newnode(x)),mg(u,L,R);
}
void del(int& u,int p) {
int L,M,R;
sp(u,p,L,R),sp(L,p-,L,M),mg(u,L,R);
}
ll qry(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
ll ret=sum[M];
mg(L,L,M),mg(u,L,R);
return ret;
}
int main() {
srand(time());
scanf("%d",&n);
ll last=;
for(int i=; i<=n; ++i) {
int a,b,c,d;
scanf("%d%d%d",&a,&b,&c),c^=last;
if(b!=)scanf("%d",&d),d^=last;
rt[i]=rt[a];
if(b==)ins(rt[i],c,d);
else if(b==)del(rt[i],c);
else if(b==)rv(rt[i],c,d);
else printf("%lld\n",last=qry(rt[i],c,d));
}
return ;
}
还有一种实现方法是去掉每个结点的随机因子,在合并的时候改用rand函数来决定哪个结点作为哪个节点的父亲,判断rand()%(siz[u]+siz[v])和siz[u]的大小关系就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e7+,inf=0x3f3f3f3f;
int ch[N][],val[N],siz[N],rev[N],tot,n,m,rt[N];
ll sum[N];
#define l(u) ch[u][0]
#define r(u) ch[u][1]
int newnode(int x) {int u=++tot; val[u]=sum[u]=x,siz[u]=,l(u)=r(u)=rev[u]=; return u;}
int cpy(int u) {int w=++tot; val[w]=val[u],sum[w]=sum[u],siz[w]=siz[u],rev[w]=rev[u],l(w)=l(u),r(w)=r(u); return w;}
void pu(int u) {siz[u]=siz[l(u)]+siz[r(u)]+,sum[u]=sum[l(u)]+sum[r(u)]+val[u];}
void pd(int u) {
if(rev[u]) {
rev[u]=;
if(l(u))l(u)=cpy(l(u));
if(r(u))r(u)=cpy(r(u));
swap(l(u),r(u));
rev[l(u)]^=,rev[r(u)]^=;
}
}
void sp(int w,int k,int& u,int& v) {
if(!w) {u=v=; return;}
pd(w);
if(k>=siz[l(w)]+)u=cpy(w),sp(r(w),k-(siz[l(w)]+),r(u),v),pu(u);
else v=cpy(w),sp(l(w),k,u,l(v)),pu(v);
}
void mg(int& w,int u,int v) {
if(!u||!v) {w=u|v; return;}
if(rand()%(siz[u]+siz[v])<siz[u])pd(u),w=u,mg(r(w),r(u),v);
else pd(v),w=v,mg(l(w),u,l(v));
pu(w);
}
void rv(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
rev[M]^=;
mg(u,L,M),mg(u,u,R);
}
void ins(int& u,int p,int x) {
int L,M,R;
sp(u,p,L,R),mg(L,L,newnode(x)),mg(u,L,R);
}
void del(int& u,int p) {
int L,M,R;
sp(u,p,L,R),sp(L,p-,L,M),mg(u,L,R);
}
ll qry(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
ll ret=sum[M];
mg(L,L,M),mg(u,L,R);
return ret;
}
int main() {
srand(time());
scanf("%d",&n);
ll last=;
for(int i=; i<=n; ++i) {
int a,b,c,d;
scanf("%d%d%d",&a,&b,&c),c^=last;
if(b!=)scanf("%d",&d),d^=last;
rt[i]=rt[a];
if(b==)ins(rt[i],c,d);
else if(b==)del(rt[i],c);
else if(b==)rv(rt[i],c,d);
else printf("%lld\n",last=qry(rt[i],c,d));
}
return ;
}
洛谷P5055 可持久化文艺平衡树 (可持久化treap)的更多相关文章
- P5055 【模板】可持久化文艺平衡树 可持久化fhqtreap
P5055 [模板]可持久化文艺平衡树 链接 luogu 思路 可持久化fhq-treap套一套就行了,pushdown和split都要可持久化,但merge不用可持久.以前以为很难一直没看,就是个板 ...
- 洛谷P5055 【模板】可持久化文艺平衡树(FHQ Treap)
题面 传送门 题解 日常敲板子.jpg //minamoto #include<bits/stdc++.h> #define R register #define inline __inl ...
- 【模板】可持久化文艺平衡树-可持久化treap
题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...
- luoguP5055 【模板】可持久化文艺平衡树 可持久化非旋转treap
好题. Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in&quo ...
- 【LG5055】可持久化文艺平衡树
[LG5055]可持久化文艺平衡树 题面 洛谷 题解 终于不可以用\(Trie\)水了... 和普通的\(FHQ\;treap\)差不多 注意一下\(pushdown\).\(split\)要新开节点 ...
- BZOJ3196 & 洛谷3380:二逼平衡树——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3196 https://www.luogu.org/problemnew/show/P3380 (题 ...
- BZOJ3223文艺平衡树——非旋转treap
此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...
- [BZOJ3223]文艺平衡树 无旋Treap
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个 ...
- 【洛谷P3835】 【模板】可持久化平衡树
可持久化非旋转treap,真的是又好写又好调 ~ code: #include <cstdio> #include <cstdlib> #include <algorit ...
随机推荐
- win10 点击开始按钮无反应
本人亲身经历 由于安装软件时需要注册表权限,在一顿猛如虎的操作下,将注册表中 HKEY_CURRENT_USER 的权限出问题.而导致无法打开 开始菜单 ----------------以下是本人为了 ...
- 关于Toad的Cannot load OCI DLL问题
昨天重新安装了新版本的JDK,突然发现Toad连接的时候报Cannot load OCI DLL....问题,网上查找了多种方法均不见效. 后调整系统环境变量配置,还原了之前安装的JDK版本,问题修复 ...
- MYSQL5.5二进制包的安装
二进制1. 下载包 wget http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.5.55-linux2.6-i686.tar.gz2. 解压 tar xx ...
- os x 技巧: 关闭打字时候光标闪烁
关闭光标闪烁: defaults write -g NSTextInsertionPointBlinkPeriodOff -float 0 defaults write -g NSTextInsert ...
- 分布式任务celery
Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成. 消息中间件 Celery本身不提 ...
- C#客户端填充外部IE浏览器中网页文本(input)且不提交
//引用COM组件//Microsoft HTML Object Library//Microsoft Internet Controls 记得改成x86 SHDocVw.ShellWindows ...
- 嵌套的JsonObject与JSONArray的取值---JSON中嵌套JSONArray
在复杂的JSON数据的格式中,往往会对JSON数据进行嵌套,这样取值会比之前的取值稍微复杂一点,但是只要思路清晰,其实取法还是一样的.就跟if else语句一样,如果if中套if,if中再套if,写的 ...
- Prometheus告警模型分析
Prometheus作为时下最为流行的开源监控系统,其庞大的生态体系:包括针对各种传统应用的Exporter,完整的二次开发工具链,与Kubernetes等主流平台的高度亲和以及由此带来的强大的自发现 ...
- 通过NGINX location实现一个域名访问多个项目
location ~ \.php$ { root /home/webroot; //此目录下有多个项目 project1 ,project2... fastcgi_pass $php_upstr ...
- 将Lambda表达式作为参数传递并解析-在构造函数参数列表中使用Lambda表达式
public class DemoClass { /// <summary> /// 通过Lambda表达式,在构造函数中赋初始值 /// </summary> /// < ...