给一个字符串,给它增加x位可以变成一个由某个前缀重复2+次构成的串,求最小的x。
如果做过白书上KMP找寻环节那个题的话,这题就没难度了...n-f[n]就是最小循环节的长度,那么我们枚举一下倍数,在k*(n-f[n])刚好>n的时候,输出他们的差即可。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn=210000;
bool ok[maxn];
int f[maxn];
char s[maxn],ss[maxn];
int cnt[maxn];
void getFail(char* P,int* f)
{
int m=strlen(P);
f[0]=0;
f[1]=0;
for (int i=1; i<m; i++)
{
int j=f[i];
while(j && P[i]!=P[j]) j=f[j];
f[i+1]=P[i]==P[j]?j+1:0;
}
}
bool find(char* T,char* P,int* f)
{
int n=strlen(T);
int m=strlen(P);
// getFail(P,f);
int j=0;
for (int i=0; i<n; i++)
{
while(j && P[j]!=T[i]) j=f[j];
if (P[j]==T[i]) j++;
if (j==m) return true;
}
return false;
}
int tt;
int n,m,k;
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&tt);
while(tt--)
{
scanf("%s",s);
getFail(s,f);
int l=strlen(s);
int size=l-f[l];
if (l%size==0 && l>size) cout<<"0\n";
else
{
for (int i=2; ; i++)
if (i*size>l)
{
cout<<i*size-l<<endl;
break;
}
}
}
return 0;
}