【LG5055】可持久化文艺平衡树

题面

洛谷

题解

终于不可以用\(Trie\)水了。。。

和普通的\(FHQ\;treap\)差不多

注意一下\(pushdown\)、\(split\)要新开节点

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <ctime>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 2e5 + 5;
struct Node {
int ls, rs, pri, val, size;
long long sum;
bool rev;
} t[MAX_N << 6];
int rub[MAX_N << 6], cur, rubtop, rt[MAX_N];
inline int newNode(int v = 0) {
int o = rubtop ? rub[rubtop--] : ++cur;
t[o].val = t[o].sum = v; t[o].pri = rand(); t[o].size = 1;
t[o].ls = t[o].rs = t[o].rev = 0;
return o;
}
inline int clone(int y) {
int x = rubtop ? rub[rubtop--] : ++cur;
t[x] = t[y];
return x;
}
inline void pushup(int o) {
t[o].size = t[t[o].ls].size + t[t[o].rs].size + 1;
t[o].sum = t[t[o].ls].sum + t[t[o].rs].sum + t[o].val;
}
inline void pushdown(int o) {
if (!t[o].rev) return ;
swap(t[o].ls, t[o].rs);
if (t[o].ls) t[o].ls = clone(t[o].ls), t[t[o].ls].rev ^= 1;
if (t[o].rs) t[o].rs = clone(t[o].rs), t[t[o].rs].rev ^= 1;
t[o].rev = 0;
}
void split(int o, int k, int &ls, int &rs) {
if (!o) ls = rs = 0;
else {
pushdown(o);
if (k <= t[t[o].ls].size) rs = clone(o), split(t[rs].ls, k, ls, t[rs].ls), pushup(rs);
else ls = clone(o), split(t[ls].rs, k - t[t[o].ls].size - 1, t[ls].rs, rs), pushup(ls);
}
}
int merge(int x, int y) {
if (!(x && y)) return x ^ y;
if (t[x].pri < t[y].pri) {
pushdown(y);
t[y].ls = merge(x, t[y].ls);
pushup(y);
return y;
} else {
pushdown(x);
t[x].rs = merge(t[x].rs, y);
pushup(x);
return x;
}
}
void insert(int &o, int k, int v) {
int x, y;
split(o, k, x, y);
o = merge(merge(x, newNode(v)), y);
}
void erase(int &o, int pos) {
int x, y, z;
split(o, pos, x, z);
split(x, pos - 1, x, y);
rub[++rubtop] = y;
o = merge(x, z);
}
void reverse(int &o, int l, int r) {
int x, y, z;
split(o, r, x, z);
split(x, l - 1, x, y);
t[y].rev ^= 1;
o = merge(merge(x, y), z);
}
long long query(int &o, int l, int r) {
int x, y, z;
split(o, r, x, z);
split(x, l - 1, x, y);
long long res = t[y].sum;
o = merge(merge(x, y), z);
return res;
}
long long ans = 0;
int N;
int main () {
srand(19260817);
N = gi();
for (int i = 1; i <= N; i++) {
int v = gi(), op = gi();
rt[i] = rt[v];
if (op == 1) { int k = gi() ^ ans, val = gi() ^ ans; insert(rt[i], k, val); }
else if (op == 2) { int k = gi() ^ ans; erase(rt[i], k); }
else if (op == 3) { int l = gi() ^ ans, r = gi() ^ ans; reverse(rt[i], l, r); }
else { int l = gi() ^ ans, r = gi() ^ ans; printf("%lld\n", ans = query(rt[i], l, r)); }
}
return 0;
}

【LG5055】可持久化文艺平衡树的更多相关文章

  1. P5055 【模板】可持久化文艺平衡树 可持久化fhqtreap

    P5055 [模板]可持久化文艺平衡树 链接 luogu 思路 可持久化fhq-treap套一套就行了,pushdown和split都要可持久化,但merge不用可持久.以前以为很难一直没看,就是个板 ...

  2. 洛谷P5055 可持久化文艺平衡树 (可持久化treap)

    题目链接 文艺平衡树的可持久化版,可以使用treap实现. 作为序列使用的treap相对splay的优点如下: 1.代码短 2.容易实现可持久化 3.边界处理方便(splay常常需要在左右两端加上保护 ...

  3. LG5055 【模板】可持久化文艺平衡树

    题意 您需要写一种数据结构,来维护一个序列,其中需要提供以下操作(对于各个以往的历史版本): 在第 pp 个数后插入数 xx . 删除第 pp 个数. 翻转区间 [l,r][l,r],例如原序列是 { ...

  4. 【模板】可持久化文艺平衡树-可持久化treap

    题目链接 题意 对于各个以往的历史版本实现以下操作: 在第 p 个数后插入数 x . 删除第 p 个数. 翻转区间 [l,r],例如原序列是 \(\{5,4,3,2,1\}\),翻转区间 [2,4] ...

  5. Luogu5055 【模板】可持久化文艺平衡树(fhq-treap)

    注意下传标记时也需要新建节点.空间开的尽量大. #include<iostream> #include<cstdio> #include<cmath> #inclu ...

  6. 洛谷P5055 【模板】可持久化文艺平衡树(FHQ Treap)

    题面 传送门 题解 日常敲板子.jpg //minamoto #include<bits/stdc++.h> #define R register #define inline __inl ...

  7. luoguP5055 【模板】可持久化文艺平衡树 可持久化非旋转treap

    好题. Code: #include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in&quo ...

  8. SLT学习——leafes tree扩展 【文艺平衡树】

    这是一个全新的数据结构 md,别看这篇文章了,这篇已经废了. 百折不饶,再交一次,更新复杂度证明 这里是HYF,蒟蒻一只,最近因某些原因开始学数据结构了,然后就写了这篇题解. 下面给大家介绍一个全新的 ...

  9. 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树

    !前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...

随机推荐

  1. 2、Sublime Text 3 快捷键(实用,快速换行等)

    选择类 Ctrl+D :选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3:选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子:快速选中并更改所有相同的变量名.函 ...

  2. C++ 异常处理机制的实现

    http://blog.jobbole.com/103925/ 本文深入讨论了VC++编译器异常处理的实现机制.附件源代码包含了一个VC++的异常处理库. 下载源代码 – 19 Kb 介绍 相对于传统 ...

  3. P2585 [ZJOI2006]三色二叉树

    题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过500000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO.OUT 输出文件也只有一行,包含两个数, ...

  4. 2、Android-UI(布局待完成)

    2.3.布局 实现界面的整齐摆放各种控件需要使用布局来完成 布局是一种可用于放置很多控件的容器 可以按照一定的规律调整内部的控件位置 布局的内部不仅可以放置控件还可以放置布局 1.线性布局 Linea ...

  5. c++ 有swap函数

    这是剑指offer数组中重复的数字那个题,直接使用的swap函数 class Solution { public: // Parameters: // numbers: an array of int ...

  6. Azure Blob数据迁移工具

    数据迁移备份,更多的应用场景见https://docs.azure.cn/zh-cn/storage/common/storage-moving-data?toc=%2fstorage%2fblobs ...

  7. jmeter接口测试1-参数化

    jmeter一个简单的接口测试例子 1.创建一个http请求: 大概的步骤就是: (1)创建一个线程组 (2)添加HTTP信息头管理器:右键线程组,选择,添加user-Agent,key-value形 ...

  8. jquery全选 反选

    //全选 反选 $('#chkAll').on('click',function(){ $('input.chkbox').prop('checked',$(this).prop('checked') ...

  9. translate动画实例

    <!doctype html> <html lang="en"> <head> <meta name="viewport&quo ...

  10. PAT——1041. 考试座位号

    每个PAT考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位.正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座 ...