解题思路
直接模拟每次操作的过程:
- 每次操作先将 1-based 的区间 [l, r] 转换为 0-based 索引
- 计算区间长度,从区间末尾向前遍历(避免插入操作影响后续字符的位置)
假设区间是 [2,4](0-based 是 [1,3]),字符是 b、c、d
如果从左到右插入:插入 b 后字符串变长,c 和 d 的位置会后移,导致后续索引计算错误
从右到左插入:先处理 d,再处理 c,最后处理 b,插入操作不会影响未处理字符的位置,保证索引准确
3.对每个字符,在其原位置后插入一个相同字符
4.重复 q 次操作后输出最终字符串
上代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
string s;
cin >> s;
while (q--)
{
int l, r;
cin >> l >> r;
int ks = l - 1; // 转换为0-based起始索引
int end = r - 1; // 转换为0-based结束索引
int len = end - ks + 1; // 区间长度
// 从区间末尾向前遍历,避免插入影响后续位置
for (int i = len - 1; i >= 0; i--)
{
int pos = ks + i; // 当前处理的字符位置
char c = s[pos]; // 获取当前字符
// 在pos+1位置插入一个字符c
s.insert(pos + 1, 1, c);
}
}
cout << s << endl;
return 0;
}
复杂度分析
时间复杂度
- 每次操作:区间长度为 k,插入 k 个字符,每个插入操作的时间复杂度是 O (m)(m 是当前字符串长度)
- 总时间复杂度:O (q * k * m)
- 由于 q≤10,初始 n≤1000,每次操作后字符串长度最多翻倍(q=10 时最大长度是 1000*2^10=1e6)不会超时
空间复杂度
- O (m):存储最终字符串,最大不超过 1e6

京公网安备 11010502036488号