2008年OI集训论文上有介绍<对块状链表的一点研究>,其主要是结合了链表和数组各自的优点,链表中的节点指向每个数据
块,即数组,并且记录数据的个数,然后分块查找和插入。在g++头文件中,<ext/rope>中有成型的块状链表,在using namespace
__gnu_cxx;空间中,其操作十分方便。
基本操作:
rope test;
test.push_back(x);//在末尾添加x
test.insert(pos,x);//在pos插入x
test.erase(pos,x);//从pos开始删除x个
test.copy(pos,len,x);//从pos开始到pos+len为止用x代替
test.replace(pos,x);//从pos开始换成x
test.substr(pos,x);//提取pos开始x个
test.at(x)/[x];//访问第x个元素
其算法复杂度n*(n^0.5),可以在很短的时间内实现快速的插入、删除和查找字符串,是一个很厉害的神器!
这里有英文版的详解:http://www.sgi.com/tech/stl/Rope.html
以上转载自:https://blog.csdn.net/piaocoder/article/details/48720007
例题:https://www.nowcoder.com/acm/contest/141/C
题意:
洗牌问题。从中间抽取连续的张牌放到牌堆顶部。进行m次操作,问最终的序列。
思路:
虽然当时想到了块状链表,但是实现太麻烦。今天看到有封装好的数据结构。
代码:
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
rope<int>s;
int main()
{
int n, m, l, k;
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) s.push_back(i+1);
while(m--)
{
scanf("%d%d", &l, &k);
s = s.substr(l-1, k) + s.substr(0, l-1) + s.substr(l-1+k, n-(l-1+k));
}
for(int i = 0; i < n; i++)
{
printf("%d", s[i]);
if(i < n-1) printf(" ");
else printf("\n");
}
return 0;
}