题意:
解题思路:
Hash做法
- 最常用的hash是进制hash
- 所以我们只要依次判断每个添加进来的字符串的每个长度,替换掉答案字符串后缀的同样长度,hash值是否相等即可
hans1[lans] == (h1 + hans1[lans - j] * ex1[j] % mod1) % mod1
//这段是替换答案后j个长度的字符串(可以将其与进制向左移联系在一起)
Kmp做法
- 待续…
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
typedef long long ll;
ll n, lans, b1, b2, mod1 = 10001227, mod2 = 10001603;
ll h1[maxn], h2[maxn], ex1[maxn], ex2[maxn];
ll hans1[maxn], hans2[maxn];
char ans[maxn], s[maxn];
void init() {
ex1[0] = ex2[0] = 1;
b1 = rand() % 321 + 233;//指数还是取随机数比较好,取2,3容易被卡
b2 = rand() % 233 + 321;
for (int i = 1; i < maxn; i++)
ex1[i] = ex1[i - 1] * b1 % mod1, ex2[i] = ex2[i - 1] * b2 % mod2;
}
int main() {
srand(time(0));
init();
//cout << b1 << " " << b2 << endl;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s + 1;
int ls = strlen(s + 1), p = 0;
ll h1 = 0, h2 = 0;
// cout << hans1[lans] << " " << hans2[lans] << endl;
for (int j = 1; j <= lans && j <= ls; j++) {
h1 = (h1 * b1 % mod1 + s[j]) % mod1;
h2 = (h2 * b2 % mod2 + s[j]) % mod2;
// cout << h1 << " " << h2 << endl;
if (hans1[lans] == (h1 + hans1[lans - j] * ex1[j] % mod1) % mod1 && hans2[lans] == (h2 + hans2[lans - j] * ex2[j] % mod2) % mod2)
p = j;
}
//cout << p << endl;
for (int j = p + 1; j <= ls; j++) {
ans[++lans] = s[j];
hans1[lans] = (hans1[lans - 1] * b1 % mod1 + s[j]) % mod1;
hans2[lans] = (hans2[lans - 1] * b2 % mod2 + s[j]) % mod2;
}
}
// cout << lans << endl;
cout << ans + 1 << endl;
}