【LG3835】可持久化平衡树
【LG3835】可持久化平衡树
题面
解法一
rope大法好
\(rope\)基本操作:
#include<ext/rope>
using namespace __gnu_cxx;//rope的命名空间
rope<type> R;
R.push_back(a) //往后插入
R.insert(pos,a)//在pos位置插入a,pos是一个迭代器。
R.erase(pos,n)//在pos位置删除n个元素。
R.replace(pos,x)//从pos开始替换成x
R.substr(pos,x)//从pos开始提取x个。
//多数时候定义rope用指针(方便可持久化) 所以上面的点多数时候要换成->
再配合二分即可实现各种操作
如何进行复制:
rope<type>* R[1000];
R[i] = new rope<type>(*R[v]);
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <ext/rope>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (ch != '-' && (ch > '9' || ch < '0')) ch = getchar();
if (ch == '-') w = -1 , ch = getchar();
while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return w * data;
}
#define MAX_N 500005
rope<int> *rop[MAX_N];
int N;
int main () {
N = gi();
rop[0] = new rope<int>();
for (int i = 1; i <= N; i++) {
int v = gi(), opt = gi(), x = gi();
rop[i] = new rope<int>(*rop[v]);
if (opt == 1) rop[i]->insert(lower_bound(rop[i]->begin(), rop[i]->end(), x) - rop[i]->begin(), x);
if (opt == 2) {
auto ite = lower_bound(rop[i]->begin(), rop[i]->end(), x);
if (ite != rop[i]->end() && *ite == x) rop[i]->erase(ite - rop[i]->begin(), 1);
}
if (opt == 3)
printf("%d\n", (int)(lower_bound(rop[i]->begin(), rop[i]->end(), x) - rop[i]->begin()) + 1);
if (opt == 4) printf("%d\n", *(rop[i]->begin() + x - 1));
if (opt == 5) {
auto ite = lower_bound(rop[i]->begin(), rop[i]->end(), x);
if (ite == rop[i]->begin() - 1) puts("-2147483647");
else --ite, printf("%d\n", *ite);
}
if (opt == 6) {
auto ite = upper_bound(rop[i]->begin(), rop[i]->end(), x);
if (ite == rop[i]->end()) puts("2147483647");
printf("%d\n", *ite);
}
}
return 0;
}
解法二
用可持久化\(trie\)可以很方便地实现
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
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 = 5e5 + 5;
const int T = 1e9;
struct Trie { int ch[2], size; } t[MAX_N << 5];
int N, rt[MAX_N], tot;
bool find(int o, int v) {
v += T;
for (int i = 31; ~i; i--) {
int c = v >> i & 1;
if (!t[o].size || !o) return 0;
o = t[o].ch[c];
}
return 1;
}
void insert(int &x, int p, int v) {
x = ++tot; int o = x;
v += T, t[o].size = t[p].size + 1;
for (int i = 31; ~i; i--) {
int c = v >> i & 1;
t[o].ch[c ^ 1] = t[p].ch[c ^ 1];
t[o].ch[c] = ++tot;
o = t[o].ch[c], p = t[p].ch[c];
t[o].size = t[p].size + 1;
}
}
void erase(int &x, int p, int v) {
if (!find(p, v)) return (void)(x = p);
x = ++tot; int o = x;
v += T, t[o].size = t[p].size - 1;
for (int i = 31; ~i; i--) {
int c = v >> i & 1;
t[o].ch[c ^ 1] = t[p].ch[c ^ 1];
t[o].ch[c] = ++tot;
o = t[o].ch[c], p = t[p].ch[c];
t[o].size = t[p].size - 1;
}
}
int Kth(int o, int k) {
long long res = -T;
for (int i = 31; ~i; i--) {
int sz = t[t[o].ch[0]].size;
if (k <= sz) o = t[o].ch[0];
else res += (1 << i), o = t[o].ch[1], k -= sz;
}
return res;
}
int LR(int o, int v) {
v += T; int res = 0;
for (int i = 31; ~i; i--) {
int c = v >> i & 1;
if (c) res += t[t[o].ch[0]].size;
o = t[o].ch[c];
if (!o || !t[o].size) return res;
}
return res;
}
int UR(int o, int v) {
v += T; int res = 0;
for (int i = 31; ~i; i--) {
int c = v >> i & 1;
if (!c) res += t[t[o].ch[1]].size;
o = t[o].ch[c];
if (!o || !t[o].size) return res;
}
return res;
}
int Rnk(int o, int v) { return LR(o, v) + 1; }
signed main () {
N = gi();
rt[0] = ++tot;
for (int i = 1; i <= N; i++) {
int v = gi(), op = gi(), x = gi();
if (op == 1) insert(rt[i], rt[v], x);
if (op == 2) erase(rt[i], rt[v], x);
if (op == 3) rt[i] = rt[v], printf("%d\n", Rnk(rt[i], x));
if (op == 4) rt[i] = rt[v], printf("%d\n", Kth(rt[i], x));
if (op == 5) {
rt[i] = rt[v];
int res = LR(rt[i], x);
if (!res) printf("%d\n", -INT_MAX);
else printf("%d\n", Kth(rt[i], res));
}
if (op == 6) {
rt[i] = rt[v];
int res = UR(rt[i], x);
if (!res) printf("%d\n", INT_MAX);
else printf("%d\n", Kth(rt[i], t[rt[i]].size - res + 1));
}
}
return 0;
}
【LG3835】可持久化平衡树的更多相关文章
- LG3835 【模板】可持久化平衡树
题意 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入x数 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作) 查询x数的排名 ...
- 可持久化Trie & 可持久化平衡树 专题练习
[xsy1629]可持久化序列 - 可持久化平衡树 http://www.cnblogs.com/Sdchr/p/6258827.html [bzoj4260]REBXOR - Trie 事实上只是一 ...
- [Luogu 3835]【模板】可持久化平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入x数 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作 ...
- 洛谷P3835 【模板】可持久化平衡树
题目背景 本题为题目 普通平衡树 的可持久化加强版. 数据已经经过强化 感谢@Kelin 提供的一组hack数据 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作( ...
- P3835 【模板】可持久化平衡树
题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本): 插入x数 删除x数(若有多个相同的数,因只删除一个,如果没有请忽略该操作) 查询x数的 ...
- [cogs2314][HZOI 2015] Persistable Editor - 可持久化平衡树
[cogs2314][HZOI 2015]Persistable Editor - 可持久化平衡树 题目链接 首先吐槽扯淡几句 [题目描述] 维护一种可持久化的文本编辑器,支持下列操作: 1 p st ...
- luoguP3835 [模板]可持久化平衡树
https://www.luogu.org/problemnew/show/P3835 因为博主精力和实力有限,学不懂 fhq treap 了,因此只介绍 leafy tree 解法 leafy tr ...
- C++ STL rope介绍----可持久化平衡树
大致介绍: rope这个东西,我刚刚知道这玩意,用的不是很多,做个简单的介绍. 官方说明:我是刘邦(我估计你是看不懂的). rope就是一个用可持久化平衡树实现的“重型”string(然而它也可以保存 ...
- Luogu P3835 【模板】可持久化平衡树(fhq Treap)
P3835 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本 ...
随机推荐
- arc093F Dark Horse
我们可以假设1的位置在1,并且依次与右边的区间合并.答案最后乘上2^n即可. 那么需要考虑1所在的区间与另一个区间合并时,另一个区间的最小值不能为特殊的. 直接求解很难,考虑容斥,钦定在哪几个位置必定 ...
- matlab中的unique函数详解
https://blog.csdn.net/sinat_40282753/article/details/78373532
- 随手练——HDU 1237 表达式求值(输入格式典型)
坑了老子半天,结果是 float 范围不够!!! 基本思想: 开一个符号栈,一个数字栈: 碰到数字就入栈,碰到符号就与栈顶符号进行对比,如果当前符号优先级小于栈顶符号,数字栈弹出两个数进行栈顶符号运算 ...
- 俄罗斯方块 UWP 版
UWP跟 WPF编程模型一致,不过UWP做了精简,而且不同的系统的API还略有不同.不同的地方有以下几点: 1.动画.动画除了故事版,还有其它的实现方式. 2.异步方法.UWP中的方法调用,大部分都是 ...
- C#回调实现的一般过程
C#回调实现的一般过程 C#的方法回调机制,是建立在委托基础之上的,下面给出它的典型实现过程. (一) 定义.声明回调 Delegate void DoSomeCallBack(type para); ...
- vue中通过定义的数组循环将img的src引入图片却不显示图片问题解决方法
需要前端循环图片数组将其放到页面中去. 需要将src渲染到页面中,如果单纯写src的路径会出现不显示图片的问题 因为图片路径在assets,所以需要require一下.
- 如何快速找到指定端口被哪个程序占用并释放该端口(解决bindException)
首先打开打开任务管理器,选择性能模块,下方有打开资源监视器,或者直接搜索资源监视器 在资源监视器中点击侦听端口模块,即可看到正在使用网络端口的应用程序名和pid,如果被占用可以直接使用命令行关闭即可 ...
- 【Java项目】GUI图形用户界面(不断更新中!)
<目录> 1 创建一个简单的窗体 2 如何进行事件监听 (1) 按钮监听 (2) 键盘监听 (3) 鼠标监听 3 容器 (1) 创建一个简单的对话框 (2) 创建一个简单的模态对话框 (3 ...
- Java基础之File类的使用
Java基础之File类的使用 1.File类的构造方法和常用方法 2.对File中listFile(FileNameFilter name)学习 3.与File文件类相关的实现 File类的构造方法 ...
- activemq的高级特性:通配符式分层订阅
activemq的高级特性之通配符式分层订阅 队列的名称可以分层:aa.bb.cc.dd 可以匹配:aa.bb.cc.dd,aa.*.cc.dd,aa.> *:匹配当前层的内容 >:任何一 ...