Rope大法(可持久化平衡树)
2008年OI集训论文上有介绍<对块状链表的一点研究>,其主要是结合了链表和数组各自的优点,链表中的节点指向每个数据
块,即数组,并且记录数据的个数,然后分块查找和插入。
头文件:#include <ext/rope>
命名空间:using namespace __gnu_cxx
基本操作:
rope test;
test.push_back(x);//在末尾添加x
ps:注意当test为rope<char>类型时只能添加单个字符而不能是字符串。
test.insert(pos,x);//在pos插入x
test.erase(pos,x);//从pos开始删除x个
test.copy(pos,len,x);//将pos开始长len个元素替换到x中
ps:注意当test为rope<char>类型时x只能为char[]而不能是string。
test.replace(pos,x);//将pos换成x
test.substr(pos,x);//提取pos开始x个
test.at(x)/[x];//访问第x个元素
test.clear();//清空元素
其算法复杂度n*(n^0.5),可以在很短的时间内实现快速的插入、删除和查找字符串,是一个很厉害的神器!
这里有英文版的详解:http://www.sgi.com/tech/stl/Rope.html
另外:
1.crope a相当于 rope<char> a
2.rope是一种非标准的STL函数,也就是说不是所有OJ都支持(具体比赛时就看人品了_(:з」∠)_)。
测试代码:
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int MAXN = 10010;
string s;
int board[MAXN];
int main(){
rope<char> ropeC;
rope<int> ropeI;
cin>>s;
cout<<"s: "<<s<<endl;
for(int i=0 ; i<=9 ; ++i){
board[i] = i;
ropeI.push_back(i);
}
cout<<"board[10]: ";
for(int i=0 ; i<=9 ; ++i)cout<<board[i]<<" ";
cout<<endl;
cout<<"ropeI: ";
for(int i=0 ; i<=9 ; ++i)cout<<ropeI[i]<<" ";
cout<<endl;
for(int i=0 ; i<s.length() ; ++i)ropeC.push_back(s[i]);
cout<<"ropeC: "<<ropeC<<endl;
cout<<endl;
cout<<"1------ .push_back(x);//在末尾添加x"<<endl;
cout<<"在ropeC末尾添加a:"<<endl;
ropeC.push_back('a');
cout<<"ropeC: "<<ropeC<<endl;
cout<<"在ropeI末尾添加7:"<<endl;
ropeI.push_back(7);
cout<<"ropeI: ";
for(int i=0 ; i<=10 ; ++i)cout<<ropeI[i]<<" ";
cout<<endl<<endl;
cout<<"2------ .insert(pos,x);//在pos位置插入x"<<endl;
cout<<"ropeC.insert(2,'c'):"<<endl;
ropeC.insert(2,'c');
cout<<"ropeC:"<<ropeC<<endl;
cout<<"ropeC.insert(2,\"ccc\"):"<<endl;
ropeC.insert(2,"ccc");
cout<<"ropeC:"<<ropeC<<endl;
cout<<"ropeI.insert(2,7):"<<endl;
ropeI.insert(2,7);
cout<<"ropeI:";
for(int i=0 ; i<=11 ; ++i)cout<<ropeI[i]<<" ";
cout<<endl<<endl;
cout<<"3------ .erase(pos,x);//从pos开始删除x个元素"<<endl;
cout<<"ropeC.erase(0,2):"<<endl;
ropeC.erase(0,2);
cout<<"ropeC:"<<ropeC<<endl;
cout<<"ropeI.erase(0,2):"<<endl;
ropeI.erase(0,2);
cout<<"ropeI:";
for(int i=0 ; i<=9 ; ++i)cout<<ropeI[i]<<" ";
cout<<endl<<endl;
cout<<"4------ .copy(pos,len,x);//将pos开始长len个元素替换到char[] x中"<<endl;
char ss[10];//注意string不行只能用char[]
cout<<"ropeC.copy(0,2,ss):"<<endl;
ropeC.copy(0,2,ss);
ss[2] = '\0';//注意加\0
cout<<"ss:"<<ss<<endl;
cout<<"ropeI.copy(0,2,board):"<<endl;
ropeI.copy(0,2,board);
cout<<"board[10]: ";
for(int i=0 ; i<=9 ; ++i)cout<<board[i]<<" ";
cout<<endl<<endl;
cout<<"5------ .replace(pos,x);//将pos换成x"<<endl;
cout<<"ropeC.replace(1,'e'):"<<endl;
ropeC.replace(1,'e');
cout<<"ropeC: "<<ropeC<<endl;
cout<<"ropeC.replace(1,\"eee\"):"<<endl;
ropeC.replace(1,"eee");
cout<<"ropeC: "<<ropeC<<endl;
cout<<"ropeI.replace(1,9):"<<endl;
ropeI.replace(1,9);
cout<<"ropeI:";
for(int i=0 ; i<=9 ; ++i)cout<<ropeI[i]<<" ";
cout<<endl<<endl;
cout<<"6------ .substr(pos,x);//提取pos开始x个元素"<<endl;
cout<<"ropeC.substr(1,3):"<<ropeC.substr(1,3)<<endl<<endl;
cout<<"7------ .at(x)/[x];//访问第x个元素"<<endl;
cout<<"ropeC.at(3):"<<ropeC.at(3)<<endl;
cout<<"ropeC[3]:"<<ropeC[3]<<endl;
cout<<"ropeI.at(3):"<<ropeI.at(3)<<endl;
cout<<"ropeI[3]:"<<ropeI[3]<<endl;
return 0;
}