裸的扩展kmp。
我的ex-kmp数组下标从0开始,用的时候处理一下就好了。
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const int maxn = 20001000;
char s[maxn], t[maxn];
ll ex[maxn], nt[maxn];
int n, m;
void get_next(void)
{
int a = 0, p = 0;
nt[0] = m;
for (int i = 1;i < m;i++)
{
if (i >= p || i + nt[i - a] >= p)
{
if (i >= p)
p = i;
while (p < m && t[p] == t[p - i])
p++;
nt[i] = p - i;
a = i;
}
else
nt[i] = nt[i - a];
}
}
void get_ex(void)
{
int a = 0, p = 0;
get_next();
for (int i = 0;i < n;i++)
{
if (i >= p || i + nt[i - a] >= p)
{
if (i >= p)
p = i;
while (p < n && p - i < m && s[p] == t[p - i])
p++;
ex[i] = p - i;
a = i;
}
else
ex[i] = nt[i - a];
}
}
int main()
{
scanf("%s%s", s, t);
n = strlen(s), m = strlen(t);
get_ex();
ll ansz=0, ansp=0;
//题目要求输出格式
for (int i = 1;i <= m;i++)
ansz ^= i * (nt[i - 1] + 1);
for (int i = 1;i <= n;i++)
ansp ^= i * (ex[i - 1] + 1);
printf("%lld\n%lld\n", ansz, ansp);
return 0;
}