LG5055 【模板】可持久化文艺平衡树
题意
您需要写一种数据结构,来维护一个序列,其中需要提供以下操作(对于各个以往的历史版本):
- 在第 pp 个数后插入数 xx 。
- 删除第 pp 个数。
- 翻转区间 [l,r][l,r],例如原序列是 {5,4,3,2,1}{5,4,3,2,1},翻转区间 [2,4][2,4] 后,结果是 {5,2,3,4,1}{5,2,3,4,1}。
- 查询区间 [l,r][l,r] 中所有数的和。
和原本平衡树不同的一点是,每一次的任何操作都是基于某一个历史版本,同时生成一个新的版本(操作 44 即保持原版本无变化),新版本即编号为此次操作的序号。
本题强制在线。
分析
函数式Treap实现。
时空复杂度\(O(n \log n)\)
代码
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
rg T data=0;
rg int w=1;
rg char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
{
data=data*10+ch-'0';
ch=getchar();
}
return data*w;
}
template<class T>T read(T&x)
{
return x=read<T>();
}
typedef long long ll;
co int N=2e5+7;
int tot;
int root[N];
int can[N],cantop;
namespace T
{
using std::swap;
int ch[N<<6][2],siz[N<<6];
int pri[N<<6],val[N<<6];
ll sum[N<<6];
bool rev[N<<6];
int newnode(int v=0)
{
int x=cantop?can[cantop--]:++tot;
ch[x][0]=ch[x][1]=0,siz[x]=1;
pri[x]=rand()<<15|rand(),val[x]=sum[x]=v;
rev[x]=0;
return x;
}
int clone(int y)
{
int x=cantop?can[cantop--]:++tot;
ch[x][0]=ch[y][0],ch[x][1]=ch[y][1],siz[x]=siz[y];
pri[x]=pri[y],val[x]=val[y],sum[x]=sum[y];
rev[x]=rev[y];
return x;
}
void pushup(int x)
{
siz[x]=siz[ch[x][0]]+1+siz[ch[x][1]];
sum[x]=sum[ch[x][0]]+val[x]+sum[ch[x][1]];
}
void pushdown(int x)
{
if(rev[x])
{
swap(ch[x][0],ch[x][1]);
if(ch[x][0])
{
ch[x][0]=clone(ch[x][0]);
rev[ch[x][0]]^=1;
}
if(ch[x][1])
{
ch[x][1]=clone(ch[x][1]);
rev[ch[x][1]]^=1;
}
rev[x]=0;
}
}
void split(int x,int k,int&l,int&r)
{
if(!x)
{
l=r=0;
return;
}
pushdown(x);
if(k<=siz[ch[x][0]])
{
r=clone(x);
split(ch[r][0],k,l,ch[r][0]);
pushup(r);
}
else
{
l=clone(x);
split(ch[l][1],k-siz[ch[x][0]]-1,ch[l][1],r);
pushup(l);
}
}
int merge(int x,int y)
{
if(!x||!y)
return x+y;
if(pri[x]<pri[y])
{
pushdown(y);
ch[y][0]=merge(x,ch[y][0]);
pushup(y);
return y;
}
else
{
pushdown(x);
ch[x][1]=merge(ch[x][1],y);
pushup(x);
return x;
}
}
void insert(int&rt,int k,int v)
{
int x,y;
split(rt,k,x,y);
rt=merge(x,merge(newnode(v),y));
}
void erase(int&rt,int p)
{
int x,y,z;
split(rt,p,x,z);
split(x,p-1,x,y);
can[++cantop]=y;
rt=merge(x,z);
}
void reverse(int&rt,int l,int r)
{
int x,y,z;
split(rt,r,x,z);
split(x,l-1,x,y);
rev[y]^=1;
rt=merge(x,merge(y,z));
}
ll query(int&rt,int l,int r)
{
int x,y,z;
split(rt,r,x,z);
split(x,l-1,x,y);
ll ans=sum[y];
rt=merge(x,merge(y,z));
return ans;
}
}
using namespace T;
using namespace std;
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n=read<int>();
ll lastans=0;
for(int i=1;i<=n;++i)
{
int v,q;
read(v),read(q);
root[i]=root[v];
if(q==1)
{
int p,x;
read(p),read(x);
p^=lastans,x^=lastans;
insert(root[i],p,x);
}
else if(q==2)
{
int p;
read(p);
p^=lastans;
erase(root[i],p);
}
else if(q==3)
{
int l,r;
read(l),read(r);
l^=lastans,r^=lastans;
reverse(root[i],l,r);
}
else
{
int l,r;
read(l),read(r);
l^=lastans,r^=lastans;
printf("%lld\n",lastans=query(root[i],l,r));
}
}
return 0;
}
LG5055 【模板】可持久化文艺平衡树的更多相关文章
- 【LG5055】可持久化文艺平衡树
[LG5055]可持久化文艺平衡树 题面 洛谷 题解 终于不可以用\(Trie\)水了... 和普通的\(FHQ\;treap\)差不多 注意一下\(pushdown\).\(split\)要新开节点 ...
- P5055 【模板】可持久化文艺平衡树 可持久化fhqtreap
P5055 [模板]可持久化文艺平衡树 链接 luogu 思路 可持久化fhq-treap套一套就行了,pushdown和split都要可持久化,但merge不用可持久.以前以为很难一直没看,就是个板 ...
- 洛谷P5055 可持久化文艺平衡树 (可持久化treap)
题目链接 文艺平衡树的可持久化版,可以使用treap实现. 作为序列使用的treap相对splay的优点如下: 1.代码短 2.容易实现可持久化 3.边界处理方便(splay常常需要在左右两端加上保护 ...
- 【模板】可持久化文艺平衡树-可持久化treap
题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...
- Luogu5055 【模板】可持久化文艺平衡树(fhq-treap)
注意下传标记时也需要新建节点.空间开的尽量大. #include<iostream> #include<cstdio> #include<cmath> #inclu ...
- 洛谷P5055 【模板】可持久化文艺平衡树(FHQ Treap)
题面 传送门 题解 日常敲板子.jpg //minamoto #include<bits/stdc++.h> #define R register #define inline __inl ...
- luoguP5055 【模板】可持久化文艺平衡树 可持久化非旋转treap
好题. Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in&quo ...
- SLT学习——leafes tree扩展 【文艺平衡树】
这是一个全新的数据结构 md,别看这篇文章了,这篇已经废了. 百折不饶,再交一次,更新复杂度证明 这里是HYF,蒟蒻一只,最近因某些原因开始学数据结构了,然后就写了这篇题解. 下面给大家介绍一个全新的 ...
- 洛谷 P3391 【模板】文艺平衡树
题目背景 这是一道经典的Splay模板题--文艺平衡树. 题目描述 您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4 ...
随机推荐
- 20145219 《Java程序设计》第06周学习总结
20145219 <Java程序设计>第06周学习总结 教材学习内容总结 InputStream与OutputStream 串流设计 1.串流:Java将输入/输出抽象化为串流,数据有来源 ...
- 并查集 试水 hdu1232
#include <stdio.h> #include <stdlib.h> int n,m; ],rank[]; int count; int find(int x) { i ...
- redis主从、集群、哨兵
redis的主从.集群.哨兵 参考: https://blog.csdn.net/robertohuang/article/details/70741575 https://blog.csdn.net ...
- 企业微信小程序--从零开始(带你见证从头开始的企业小程序之开发运营)
1.注册微信小程序账户(自己摸索吧很简单的) 2.微信小程序认证 3.遇到的问题 1)
- QT treewidget 右键菜单
VS2012+QT5.2 ,没有ui,纯代码实现右键 方法一:常规但略麻烦 1.头文件slot中声明 QTreeWidget *tree; void showrightMenu(QPoint);//显 ...
- Java内存分析1 - 从两个程序说起
这次看一些关于JVM内存分析的内容. 两个程序 程序一 首先来看两个程序,这里是程序一:JVMStackTest,看下代码: package com.zhyea.robin.jvm; public c ...
- 落地案例|日本雅虎如何在 OpenStack 上大规模构建和运行 Kubernetes
今天的帖子是由日本雅虎的基础设施工程团队撰写,内容是他们如何在 Kubernetes 上运行 OpenStack.这篇帖子是由日本雅虎的工程博客编译而来. 简介: 这篇帖子大致描述了日本雅虎在 Goo ...
- Eclipse的编码格式设置
在使用Eclipse开发中,许多文件编码默认是ISO-8859-1,不支持中文(如常用的JSP).这样我们每次建文件都要手动改编码,其实我们可以在设置文件默认编码,今后再创建时就不用每次修改编码了, ...
- C++(十八) — 内存模式、堆和栈
1.内存模式 一个程序执行时,先复制到内存,然后CPU逐句读取指令执行. 每个存储单元存放一个字节(8bit)数据,每个有一个唯一的地址,地址是顺序编码的.比如:一台计算机256MB内存,则有256* ...
- jmeter导入jar包后在beanshell中import失效的问题解决
最近一直很忙,没有时间来更新了,今天抽空把之前遇到的问题记录下来. 之前在使用jmeter做http请求性能压测时,因为要对所有入参做排序再加密作为一个入参,所以写了一段java代码,用来处理入参,打 ...