【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 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本 ...
随机推荐
- python中执行shell命令
查看输出结果 import os output = os.popen('cat 6018_gap_5_predict/solusion2/solusion2_0-1.txt | wc -l') pri ...
- 【bzoj2154】Crash的数字表格 莫比乌斯反演
题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, ...
- Hadoop学习之路(二十七)MapReduce的API使用(四)
第一题 下面是三种商品的销售数据 要求:根据以上数据,用 MapReduce 统计出如下数据: 1.每种商品的销售总金额,并降序排序 2.每种商品销售额最多的三周 第二题:MapReduce 题 现有 ...
- 20155328 2016-2017-2 《Java程序设计》第九周学习总结
20155328 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 16.1 JDBC入门 JDBC是Java联机数据库的标准规范,定义一组标准类与接口,应用程 ...
- Notepad++格式化JSON字符串
窗口 -> 插件 -> Plugin Manager -> Show Plugin Manager,在弹出层中找到"JSON Viewer"选项,将踏勾选上,然后 ...
- PAT——1069. 微博转发抽奖
小明PAT考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔N个人就发出一个红包.请你编写程序帮助他确定中奖名单. 输入格式: 输入第一行给出三个正整数M(<= 1000).N ...
- SDOI2018一轮NOI培训 题目整理
\(qwq\)首先,这些题对于我而言--类似于\(emmm\)洪水猛兽 \(\mathcal{Day \ \ 1}\) T1 \(\mathcal{\color{red}{Description}}\ ...
- Python 基础 函数
python 什么是函数 Python不但能非常灵活地定义函数,而且本身内置了很多有用的函数,可以直接调用. python 函数的调用 Python内置了很多有用的函数,我们可以直接调用. 要调用 ...
- 19-3-13Python中的函数
def:关键字.定义.声明一个函数. def make():定义函数'make' *注:定义后的函数不调用是不执行的 函数的调用: 函数名+()==函数的调用 def addnum(): a = in ...
- linux查看网卡地址和硬盘序列号
linux查看网卡地址命令:ifconfig linux查看硬盘序列号命令:hdparm -i /dev/sda