鹤岗市网站建设_网站建设公司_HTML_seo优化
2026/1/16 21:50:57 网站建设 项目流程

字符串问题

大意

插入字符,查询字符。
初始串 \(s\), \(|s| \le 10^6\)

思路

可以用平衡树,但是我选择更为强势的 STL 中的 rope。

头文件:#include<ext/rope>

crope r1;           // 存储 char 的 rope
wrope r2;           // 存储 wchar_t 的 rope
rope<long long> r3; // 也可以存储其他基本类型

rope 的大部分操作复杂度均为 \(O(\log n)\),底层基于可持久化平衡树实现。

函数名 功能描述 示例用法
push_back(x) 在末尾添加单个字符 r.push_back('a');
append(s) 在末尾追加字符串/rope r.append("abc");
insert(pos, s) pos 位置插入字符串/rope r.insert(2, "xyz");
erase(pos, n) pos 开始删除 n 个字符 r.erase(1, 10);
replace(pos, n, s) posn 个字符替换为 s r.replace(1, 2, "ok");
substr(pos, n) 提取从 pos 开始的 n 个字符 crope sub = r.substr(2, 3);
at(i)[i] 访问下标为 i 的字符 char c = r[0];
size() 返回当前长度 int len = r.size();

rope 最强大的特性在于它支持 \(O(1)\) 的对象拷贝,这使得它能以极低的时间和空间成本维护历史版本。

当你将一个 rope 赋值给另一个时,底层并不拷贝树结构,而是增加引用计数。只有在其中一个对象发生修改时,才会局部复制受影响的节点。

crope r1 = "v1_data"; 
crope r2 = r1;         // O(1) 拷贝,此时 r1 和 r2 共享底层节点
r2.insert(0, "new_");  // 修改 r2,r1 保持不变(自动实现可持久化)

如果题目要求查询“第 k 次操作后的状态”,可以直接开一个 rope 数组记录快照:

crope history[MAX_VERSION];int main() {history[0] = "initial_state"; // 初始状态for(int i = 1;i <= m;++ i){history[i] = history[i - 1]; // O(1) 继承上一个版本// 在当前版本上进行操作int opt, pos; char c;cin >> opt >> pos >> c;if(opt == 1){// 修改当前版本,不会影响 history[i - 1]history[i].insert(pos, c);}}
}

记得加:using namespace __gnu_cxx;

代码

#include<iostream>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;string s;
int m;
crope r;int main(){cin >> s;cin >> m;r.append(s.c_str());while(m --){char op;cin >> op;if(op == 'I'){char c; int p; cin >> c >> p;if(p > r.size()){r.append(c);}else{r.insert(p - 1, crope(1, c));}}else{int x; cin >> x;cout << r[x - 1] << '\n';}}return 0;
}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询