0%

CF1200E Compress Words

传送门

Solution

设当前待合并的串为 AA,已合并的串为 BB。若 AB|A|\ge |B|,则 C=A+BC=A+B。否则 CC 等于 AABB 长度为 A|A| 的后缀拼接而成的字符串。对 CC 进行 KMP,求出最大相同前后缀长度 nxtCnxt_{|C|}。把 AA 的相应长度后缀并入 BB 后面即可。

为防止出现错误,可以在 AABB 中间插入字符 #

时间复杂度 O(si)O(\sum |s_i|)

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
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

int n, nxt[2000010];
string s, ans;

int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
cin >> s;
if (i == 1) {
ans = s;
continue;
}
string str; int k = 0, len = s.size();
s += "#";
if (len < ans.size())
str = s + ans.substr(ans.size() - len, len);
else
str = s + ans;
nxt[0] = nxt[1] = 0;
for (int j = 1; j < str.size(); j++) {
while (k > 0 && str[k] != str[j])
k = nxt[k - 1];
if (str[k] == str[j])
++k;
nxt[j] = k;
}
ans += s.substr(nxt[str.size() - 1], len - nxt[str.size() - 1]);
}
cout << ans << endl;
return 0;
}