题意:
给定一个包含
1...
n
1...n
1...n的数列,
n
n
n个数顺序排放,随后有
m
m
m次操作,每次选定一个连续的区间,将该区间的所有数移动到数列的最前端,问
m
m
m次操作以后的数列是什么?
思路:
队友用Splay一发过的,赛后看群内大佬们聊天记录才发现还可以用
r
o
p
e
rope
rope水过。
在g++头文件中,同时需要使用特定的命名空间:
#include<ext/rope>
using namespace __gnu_cxx;
其本质是一个块状链表,通过平衡数组和链表操作的复杂度,使得其维护的数列操作时间复杂度为 O ( n ) O(\sqrt n) O(n),故也可以看成是一个可持久化平衡树。
其常用操作如下:
def | 功能 |
---|---|
push_back(x) | 在末尾追加x |
insert(pos,x) | 在pos插入x |
erase(pos,x) | 从pos开始删除连续x个元素 |
replace(pos,x) | 从pos开始替换成x |
substr(pos,x) | 提取从pos开始的x个元素 |
at(x) or [x] | 访问第x个元素 |
代码:
#include<cstdio>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
rope<int> a;
int main(){
int n,m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) a.push_back(i);
for (int i = 1; i <= m; i++) {
int x, y;
scanf("%d%d", &x, &y);
a.insert(0, a.substr(x - 1, y));
a.erase(x + y - 1, y);
}
for (int i = 0; i < n; i++) printf("%d%c", a[i], i == n - 1?'\n':' ');
return 0;
}