P4008 [NOI2003]文本编辑器

我愿称之为最强 $STL$ !!!

Rope

学习了一种超级强大的 $STL$ ,甚至于很多竞赛禁止使用。

$rope$

非标准 $STL$ ,仅能在 $C++11$ 以后使用。

需要头文件 #include<ext/rope>

并需要 using namespace __gnu_cxx;

定义为 rope<变量类型>变量名crope 变量名称

crope R 其实就是 rope<char>R

结合了链表数组各自优点的块状链表。内部结构可持久化平衡树红黑树

操作

push_back(x) : 在末尾添加 $x$ ( $x$ 是 char 类型的)。

insert(pos,x):在 $pos$ 插入 $x$ ( $x$ 是字符串, $x$ 后面加个 $int$ 参数可以只能 $x$ 中插入几个)。

erase(pos,x): 从 $pos$ 开始删除 $x$ 个。

replace(pos,x): 从 $pos$ 开始换成 $x$ ( $x$ 是字符串, $x$ 后面加个 $int$ 参数可以只能 $x$ 中的前几个)。

substr(pos,x)提取 $pos$ 开始 $x$ 个。

copy(pos,len,x):从 $pos$ 到 $pos+len$ 替换成 $x$ 。

访问:同数组,用R[x]即可。大部分操作都是 $O(\log n)$ 的复杂度。

该题

当用上 $rope$ 后,可持久的紫题没有丝毫威严。

吸氧过:

AC Code

查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<iomanip>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<ext/rope>
#define gh() getchar()
#define re register
#define underMax(x,y) ((x)>(y)?(x):(y))
#define underMin(x,y) ((x)<(y)?(x):(y))
typedef long long ll;
using namespace std;
using namespace __gnu_cxx;
template<class T>
inline void underRead(T &x)
{
x=0;
char ch=gh(),t=0;
while(ch<'0'||ch>'9') t|=ch=='-',ch=gh();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=gh();
if(t) x=-x;
}
int N,pos;
string Str;
rope<char>R;
int main()
{
// freopen("rope.in","r",stdin);
// freopen("rope.out","w",stdout);
underRead(N);
for(int i=1;i<=N;++i)
{
cin>>Str;
if(Str[0]=='M')
{
int k;
underRead(k);
pos=k;
}
else if(Str[0]=='I')
{
int n;
underRead(n);
char ch;
for(int i=0;i<n;++i)
{
ch=gh();
if(ch<32||ch>126) --i;
else R.insert(pos+i,ch);
}
}
else if(Str[0]=='D')
{
int n;
underRead(n);
R.erase(pos,n);
}
else if(Str[0]=='G')
{
int n;
underRead(n);
for(int i=0;i<n;++i) cout<<R[pos+i];
puts("");
}
else if(Str[0]=='P') --pos;
else ++pos;
}
return 0;
}
/*
15
Insert 26
abcdefghijklmnop
qrstuv wxy
Move 15
Delete 11
Move 5
Insert 1
^
Next
Insert 1
_
Next
Next
Insert 4
.\/.
Get 4
Prev
Insert 1
^
Move 0
Get 22

10
Insert 5 opres
Get 3
Next
Next
Get 3
Insert 10 undertales
Move 6
Get 10
Delete 1
Get 9
*/