【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 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本 ...
随机推荐
- Android 之 GridView具体解释
工作这么久以来,都是以解决需求为目标.渐渐发现这样的学习方式不好,学到的知识能立即解决这个问题,但没有经过梳理归纳. 故想系统总结下一些有趣味的知识点. 在这篇博客中想以一个样例系统解说下GridVi ...
- chrome下载离线安装包的方法
https://www.google.com/chrome/browser/desktop/index.html?system=true&standalone=1,一般默认下载稳定版,如果需要 ...
- 关于SpringMVC整合freemarker报错问题
错误信息: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'FreeMa ...
- Android-社会化分享
2016年2月25日下午3点:现在无事,整理下这两天在网上搜集到的乱起八糟的东西和我的思路. 关于对社会化分享的了解,源于前天的一次apk打包操作.现在的情况是:开发编写功能代码提交SVN,我把代码d ...
- C++11之std::future和std::promise
为什么C++11引入std::future和std::promise?C++11创建了线程以后,我们不能直接从thread.join()得到结果,必须定义一个变量,在线程执行时,对这个变量赋值,然后执 ...
- 公司内网静态IP,外网无线动态IP 同时上网,不必再切换网卡啦 route 命令给你搞定。
一: 公司内网:192.168.55.101 255.255.255.0 192.168.55.1 网关 外网:192.168.20.101 255.255.255.0 192.16 ...
- vue+echarts实现可拖动节点的折现图(支持拖动方向和上下限的设置)
本篇文档主要是利用echarts实现可拖动节点的折现图,在echarts中找到了一个demo,传送门:https://echarts.baidu.com/examples/editor.html?c= ...
- 底层文件I/O操作中read()函数的缓存问题
最近在学习Linux过程中看到文件I/O操作这里时,文件I/O操作的系统调用涉及的5个函数:open(),read(),write(),lseek(),close().在一开始就阐明这些函数的特点是不 ...
- activemq的搭建、启动,简单demo
一.搭建activeMQ 在官网下载window版本,直接解压就可以. 二.启动 在解压完的目录/bin/win64,双击击activemq.bat,运行完之后打开浏览器,输入http://127.0 ...
- swiper在vue中正确的使用方法
1.安装swiper,执行npm install vue-awesome-swiper --save命令 2.在main.js中添加下面三行 import 'swiper/dist/css/swipe ...