rope (类似于块状链表的结构)
需要增加的预处理指令:
#include<ext/rope>
using namespace __gnu_cxx;
rope<int> rp;
基本操作:
在末尾插入 (x) : rp.push_back(x);
在 (pos) 处插入 (x) : rp.insert(pos, x);
从 (pos) 处开始删除 (x) 个元素: rp.erase(pos, x);
返回 (rp) 的大小: rp.length();
或 rp.size();
将 (pos) 处的元素替换成 (x): rp.replace(pos, x);
获取从 (pos) 处开始的 (x) 个元素: rp.substr(pos, x);
将从 (pos) 处开始的 (x) 个元素复制到 (s) 中: rp.copy(pos, x, s);
访问第 (x) 个元素: rp[x];
或 rp.at(x);
拷贝历史版本:
rope<int> *his[1000];
his[i] = new rope<int> (*his[i - 1]);
[AHOI2006]文本编辑器
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int N = 2e6 + 20;
int n;
int x, pos, len;
char s[N], opt[10], revs[N];
rope<char> a, b, tmp;
int main()
{
scanf("%d", &n);
while(n -- )
{
scanf("%s", opt);
switch(opt[0])
{
case 'M': scanf("%d", &x); pos = x; break;
case 'I': scanf("%d", &x); getchar(); len = a.size();
for(int i = 0; i < x; ++ i)
{
s[i] = getchar();
revs[x - 1 - i] = s[i];
}
revs[x] = s[x] = 0;
a.insert(pos, s);
b.insert(len - pos, revs);
break;
case 'D': scanf("%d", &x); len = a.size();
a.erase(pos, x);
b.erase(len - pos - x, x);
break;
case 'R': scanf("%d", &x); len = a.size();
tmp = a.substr(pos, x);
a = a.substr(0, pos) + b.substr(len - pos - x, x) + a.substr(pos + x, len - pos - x);
b = b.substr(0, len - pos - x) + tmp + b.substr(len - pos, pos);
break;
case 'G': if(a[pos] != '
') printf("%c
", a[pos]);
else puts(""); break;
case 'P': pos --; break;
case 'N': pos ++; break;
}
}
return 0;
}
[NOI2003] 文本编辑器
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int N = 3e6 + 20;
int n;
int x, pos;
char s[N], opt[10];
rope<char> a;
int main()
{
scanf("%d", &n);
while(n -- )
{
scanf("%s", opt);
switch(opt[0])
{
case 'M': scanf("%d", &x); pos = x; break;
case 'I': scanf("%d", &x);
for(int i = 0; i < x; ++ i)
{
s[i] = getchar();
while(s[i] == '
' || s[i] == '
') s[i] = getchar();
}
s[x] = 0; a.insert(pos, s); break;
case 'D': scanf("%d", &x); a.erase(pos, x); break;
case 'G': scanf("%d", &x); a.copy(pos, x, s); s[x] = 0; puts(s); break;
case 'P': pos --; break;
case 'N': pos ++; break;
}
}
return 0;
}