洛谷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 ...
随机推荐
- jenkins提示反向代理设置有误
jenkins提示反向代理设置有误 参照地址 https://www.cnblogs.com/yhleng/p/7594892.html 分析:是junkins的url地址填错了 解决: 系统管理-- ...
- MySQL 5.7.27 MGR 单主/多主+ ProxySQL
1 MySQL 5.7.27 MGR 多主环境 基础信息如下: centos 6.5/vbox 实例名 A B C IP 10.15.7.29 10.15.7.28 10.15.7.27 实例端口号 ...
- composer配合github发布管理代码包
前言 今日使用composer结合github管理代码包过程,方便日后需要,特此记录 流程 1 最大同性交友网站github创建自己项目,在自己项目新增composer.json文件 2 compos ...
- jqueryweui关于switch css与js结合
.invoice_wrapper{ .comm_con{ .weui-switch-cp{ .weui-switch-cp__box{ height:0.4rem; margin:0.25rem 0; ...
- numpy使用数组进行数据处理
numpy使用数组进行数据处理 meshgrid函数 理解: 二维坐标系中,X轴可以取三个值1,2,3, Y轴可以取三个值7,8, 请问可以获得多少个点的坐标? 显而易见是6个: (1,7)(2,7) ...
- MacOS 下文件读取问题
使用Xcode编写C++程序可以直接使用fstream读写文件,代码如下: const char* path1 = [path UTF8String];string filename = path1; ...
- 如何快速的查找服务所在的进程id?
执行 pgrep -l 服务名称 这里以查找redis所在的进程id为例 执行 pgrep -l redis 从图中可知进程id 为30058
- Druid + spring 配置数据库连接池
1. Druid的简介 Druid是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBo ...
- 19.AutoMapper 之开放式泛型(Open Generics)
https://www.jianshu.com/p/ce4c7e291408 开放式泛型(Open Generics) AutoMapper可以支持开放式泛型的映射.为开放式泛型创建映射: publi ...
- Python类函数调用:missing 1 required positional argument
在Python中,应该先对类进行实例化,然后在应用类.注意,实例化的过程是应该加括号的.