题解:AT_abc419_d [ABC419D] Substr Swap
CodeSage_Hu · · 题解
题意简述
有两个长度为
每次操作交换
求
数据范围:
-
N \leq 5\times 10^5 -
M \leq 2\times 10^5
思路分析
直接模拟的复杂度
如果每次真的去交换区间内的字符,最坏情况复杂度
高效做法
我们可以利用 rope 数据结构(一个非标准的STL工具)来高效完成区间交换。
rope 支持:
- 提取子串
O(\log N) - 替换子串
O(\log N)
这样每次操作只需提取两段子串并交换,复杂度
算法步骤
- 读入
N, M, S, T 和操作区间。 - 将
S 和T 存入两个rope<char>。 - 对每个操作
[L, R] (转为 0-based):- 从
S 中提取[L, R] 子串subS - 从
T 中提取[L, R] 子串subT - 将
S 的[L, R] 替换为subT - 将
T 的[L, R] 替换为subS
- 从
- 将最终的
S 转换为字符串输出。
代码实现
#include <iostream>
#include <string>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
string s, t;
cin >> s >> t;
rope<char> rs(s.c_str()), rt(t.c_str());
for (int i = 0; i < M; i++) {
int L, R;
cin >> L >> R;
L--; R--;
auto subS = rs.substr(L, R - L + 1);
auto subT = rt.substr(L, R - L + 1);
rs.replace(L, R - L + 1, subT);
rt.replace(L, R - L + 1, subS);
}
string ans;
for (int i = 0; i < N; i++)
ans += rs[i];
cout << ans << '\n';
return 0;
}