洛谷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 ...
随机推荐
- robotframework 配置过程中遇到的问题
现有环境配置:操作系统: Win7 32bitPython 2.7.8Python 3.5.2Pycharm Community Edition 2016.3.2robotframework: 3.0 ...
- 【Java基础】JAVA 使用线程的几种方式
之前放在自己网站上的例子,因为网站关闭,已经找不到了,想用的时候,没有的话又重新翻书是很麻烦的事情.所以重新记录一下,以备将来查看. 第一种,让任务类继承Runable接口,然后将任务类对象放入Thr ...
- 双屏显示——NW.js
1.利用w10中的双屏显示设置(扩展模式) 2.Code for second window: var gui = require('nw.gui'); gui.Screen.Init(); win ...
- Could not find aapt Please set the ANDROID_HOME environment variable with the Android SDK root directory path
写case写好好哒,突然debug的时候就冒出这个错误: selenium.common.exceptions.WebDriverException: Message: An unknown serv ...
- cocos2dx[3.2](5) 屏幕适配
1.两个分辨率 1.1.窗口分辨率 在AppDelegate.cpp中有个设置窗口分辨率的函数.该函数是设置了我们预想设备的屏幕大小,也就是应用程序窗口的大小. // glView->setFr ...
- Java多线程ThreadLocal介绍
在Java多线程环境下ThreadLocal就像一家银行,每个线程就是银行里面的一个客户,每个客户独有一个保险箱来存放金钱,客户之间的金钱不影响. private static ThreadLocal ...
- MSF魔鬼训练营第一章 初识Metasploit
1.1.4渗透测试过程环节 PTES标准7个阶段 1.前期交互阶段 收集客户需求.准备测试计划.定义测试范围与边界.定义业务目标.项目管理与规划等 2.情报搜集阶段 公开来源信息查 ...
- c语言l博客作业07
一.本周教学内容&目标 第3章 分支结构 3.3 使学生熟悉多分支结构switch语句的使用. 二.本周作业头 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://e ...
- BUUOJ reverse 刮开有奖
刮开有奖 这是一个赌博程序,快去赚钱吧!!!!!!!!!!!!!!!!!!!!!!!!!!!(在编辑框中的输入值,即为flag,提交即可) 注意:得到的 flag 请包上 flag{} 提交 拖到id ...
- mysql的高可用之rounter
参考: https://segmentfault.com/a/1190000011970688