单题分析:NOI2014 动物园。
题目分析:很明显题目已明确指出这是有关KMP的题,思考KMP。本题与普通KMP不同之处在于它求的是不相交最长相同前缀后缀。
如何处理不相交:
1.暴力
2.注意一件事:两个相同的串,前缀与后缀相同,即同一个串,前缀的前缀等于后缀的后缀(这里是前缀与后缀相等的前缀与后缀),即当KMP[i]超过串的一半长度时,对此时的前缀与后缀分别求其的前缀与后缀(同上),直到其长度小于等于串的一半长度。
3.关键:前缀与后缀相同。
#include <bits/stdc++.h> using namespace std; long long n; char c[1000002]; long long kmp[1000002],ans[1000002]; int main() { scanf("%lld",&n); while(n--) { memset(ans,0,sizeof(ans)); memset(kmp,0,sizeof(kmp)); scanf("%s",c + 1); long long j = 0; ans[1] = 1; long long lena = strlen(c + 1); for(long long i = 2;i <= lena;i++) { while(j && c[i] != c[j + 1])j = kmp[j]; if(c[i] == c[j + 1])j++; ans[i] = ans[j] + 1; kmp[i] = j; } j = 0; long long out = 1; for(long long i = 2;i <= lena;i++) { while(j && c[i] != c[j + 1])j = kmp[j]; if(c[i] == c[j + 1])j++; while(j > i / 2)j = kmp[j]; out = (out * (ans[j] + 1)) % 1000000007; } printf("%lld ",out); } return 0; }