Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=3336
Problem-solving ideas:
First original array configuration mismatch Array
fail [i] denotes 0 ~ i-1 before the longest common suffix
First, we shilling ans = len, is the first to add each prefix itself
We can guarantee that will not coincide with those obtained in the suffix array fail, otherwise called the prefix.
Next traversal fail [2] ~ fail [len]
For each of us fail to find all i-1 to the end of the suffix suffix
First, the current fail [i] is not 0, then there must be 0 ~ x == i-1-x ~ i-1
And we ensure that no suffix was previously counted, because before i-1 had not ending with the suffix
We all want to get to i-1 suffix of how to do, is to go back along the side of the mismatch, see fail [fail [i]] is greater than 0, greater than 0 can prove from the i-1-x ~ i- then cutting out a 1 i-1 at the end of the shorter extension, look fail [fail [fail [i]]] until this value is not greater than zero.
Code:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 10007
using namespace std;
const int N = 2e5+5;
char s[N];
int fail[N];
void kmp(int len)
{
fail[0] = -1;
for (int i=0,j=-1;i<len;){
if (j==-1||s[i]==s[j]){
i++;j++;
fail[i] = j;
}
else j = fail[j];
}
int ans = len%mod;
for (int i=2;i<=len;i++){
if (fail[i]>0) ans++;
int now = fail[i];
while (fail[now]>0){
ans++;
now = fail[now];
}
}
printf("%d\n",ans%mod);
}
int main()
{
int T;
scanf("%d",&T);
while (T--){
int n;
scanf("%d",&n);
scanf("%s",s);
kmp(n);
}
return 0;
}
I do not know think is not complicated, if later felt easier way from another title to change it back