来学了一下扩展KMP,改了四道晚自习的代码,今晚终于过了,我真的会谢,一些小细节问题
//扩展z函数(kmp扩展)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e7+10;
int z[N],p[N];
char a[N],s[N];
void get_z(char *s,int n)
{
z[1] = n;
for(int i = 2,l,r = 0;i <= n;i++)
{
if(i <= r)z[i] = min(z[i-l+1],r - i + 1);
while(s[1+z[i]] == s[i+z[i]]) z[i]++;
if(i+z[i]-1 > r) l = i,r = i+z[i]-1;
}
}
void get_p(char *s,int n,char *a,int m)
{
for(int i = 1,l,r = 0;i <= m;i++)//这里的边界是m!!!!!
{
if(i <= r)p[i] = min(z[i-l+1],r - i + 1);
while(1+p[i] <= n && i+p[i] <= m && s[1+p[i]] == a[i+p[i]]) p[i]++;
if(i+p[i]-1 > r) l = i,r = i+p[i]-1;
}
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0);//一定要取消同步流
cin>>a+1>>s+1;
int m = strlen(a+1);
int n = strlen(s+1);
get_z(s,n);
get_p(s,n,a,m);
ll ans1 = 0,ans2 = 0;
for(int i = 1;i <= n;i++) ans1 ^= 1ll * i * (z[i]+1);
for(int i = 1;i <= m;i++) ans2 ^= 1ll * i * (p[i]+1);
cout<<ans1<<endl<<ans2;
return 0;
}
kmp和扩展kmp的区别就在