【uoj5】 NOI2014—动物园
http://uoj.ac/problem/5 (题目链接)
题意
求字符串各个前缀的前缀与后缀相同但不重叠的子串的个数+1之积
Solution
KMP。第一遍求next和符合条件的可以重叠的子串。第二遍,求符合条件的不重叠的子串,注意此时不可以重新求next,直接使用上次求出来的next。
代码
// uoj5 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf (1ll<<30) #define MOD 1000000007 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=1000010; int next[maxn],num[maxn],sum[maxn]; char s[maxn]; int main() { int T;scanf("%d",&T); while (T--) { scanf("%s",s+1); int n=strlen(s+1); next[1]=0;sum[0]=-1;num[0]=-1; for (int j=0,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;sum[i]=sum[j]+1; } for (int j=0,i=2;i<=n;i++) { while (j && (s[j+1]!=s[i] || j+1>i/2)) j=next[j]; if (s[j+1]==s[i]) j++; num[i]=sum[j]+1; } LL ans=1; for (int i=1;i<=n;i++) ans=ans*(num[i]+1)%MOD; printf("%lld\n",ans); } return 0; }
This passage is made by MashiroSky.