[POI2006]OKR-Periods of Words(KMP)
题意:给定一个字符串,求它的每个前缀的的一个最长前缀,使得它重复两边后能够覆盖原串。
Solution
这题显然要在KMP的next数组上做一些手脚。
对于一个前缀,我们把它重复两遍,那么这个前缀的前缀是这个串的后缀(可以忽略这句话)。
那么我们需要求出这个串的最短前缀等于后缀。
Code
#include<iostream> #include<cstdio> #define N 1000009 using namespace std; int next[N],j,n; long long ans; char s[N]; int main() { scanf("%d%s",&n,s+1); for(int i=2;i<=n;++i) { while(j&&s[j+1]!=s[i])j=next[j]; if(s[j+1]==s[i])++j; next[i]=j; } for(int i=1;i<=n;++i) { j=i; while(next[j])j=next[j]; if(next[i])next[i]=j;//you hua ans+=i-j; } cout<<ans; return 0; }
#include<iostream> #include<cstdio> #define N 1000009 using namespace std; int next[N],j,n; long long ans; char s[N]; int main() { scanf("%d%s",&n,s+1); for(int i=2;i<=n;++i) { while(j&&s[j+1]!=s[i])j=next[j]; if(s[j+1]==s[i])++j; next[i]=j; } for(int i=1;i<=n;++i) { j=i; while(next[j])j=next[j]; if(next[i])next[i]=j;//you hua ans+=i-j; } cout<<ans; return 0; }