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;
}

posted @ 2018-07-27 10:34  Assassin_poi君  阅读(306)  评论(0编辑  收藏  举报