2020牛客国庆集训派对day8 G-Shuffle Cards(扩展STL容器,rope可持久化平衡树)

2020牛客国庆集训派对day8 G-Shuffle Cards(扩展STL容器,rope可持久化平衡树)

题目

https://ac.nowcoder.com/acm/contest/7865/G

题意

给你n张牌,要你洗k次牌。
后面k行数据,p,s表示将第p张牌后的s张牌,放到牌顶。
让你求k次操作之后牌的顺序。

题解

这就很明显是个区间插入、删除的操作模拟,可是因为n,k都是1e5的,所以正常用vector写肯定TLE。在这里就需要用到神奇的东西——rope容器。

rope是什么?

rope 不属于标准 STL,属于扩展 STL,来自 pb_ds 库 (Policy-Based Data Structures)

它的头文件:#include<ext/rope> (注:可以打开devcpp的目录去rope这个头文件看看它的操作)

它的名称空间:using namespace __gnu_cxx;

定义方法:rope<变量类型>变量名称;

或    crope 变量名称;

其中crope相当于定义成rope < char >,即定义为string类型

rope 解释

算法解释:块状链表(即讲链表与数组的优势结合,形成分块思想)

用途解释:这本来是一个用于快速操作string的工具,却一般被定义成int,然后用作可持久化线段树!

rope 内部是块状链表实现的,黑科技是支持 O(1) 复制,而且不会空间爆炸 (rope 是平衡树,拷贝时只拷贝根节点就行)。因此可以用来做可持久化数组。
经典的可持久化线段树的图解
在这里插入图片描述

支持的操作:

#include <ext/rope>  // 头文件
using namespace __gnu_cxx;  // 注意名称空间

rope<int> rp;

int main() {
    rp.push_back(x); // 在末尾插入 x
    rp.insert(pos, x); // 在 pos 处插入 x
    rp.erase(pos, x); // 在 pos 处删除 x 个元素
    rp.length(); // 返回 rp 的大小
    rp.size(); // 同上
    rp.replace(pos, x); // 将 pos 处的元素替换成 x
    rp.substr(pos, x); // 从 pos 处开始提取 x 个元素
    rp.copy(pos, x, s); // 从 pos 处开始复制 x 个元素到 s 中
    rp[x]; // 访问第 x 个元素
    rp.at(x); // 同上
    return 0;
}

AC 代码

#include <bits/extc++.h>
#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_cxx;
const int N = 100010;

int main() {
	int n, m, a[N] = {0}; cin >> n >> m;
	for (int i = 0; i < n; i++) a[i] = i + 1;
	rope<int> rp(a);
	while (m--) {
		int p, s; cin >> p >> s; p--;
		rp.insert(0, rp.substr(p, s));
		rp.erase(p + s, s);
	}
	for (auto i : rp) cout << i << " ";
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值