BZOJ 3670: [Noi2014]动物园 KMP
暴力的做法是求出 $next$ 数组后倍增求解答案.
但实际上不用这么麻烦,再做一次类似于 KMP 的东西就可以了.
code:
#include <bits/stdc++.h> #define N 1000006 #define ll long long #define setI(s) freopen(s".in","r",stdin) #define setO(s) freopen(s".out","w",stdout) using namespace std; const ll mod=1000000007; int fail[N],num[N]; char str[N]; void solve() { scanf("%s",str+1); int n=strlen(str+1); for(int i=1;i<=n;++i) fail[i]=num[i]=0; fail[1]=0,num[1]=1; int pre=0; for(int i=2;i<=n;++i) { for(;pre&&str[pre+1]!=str[i];pre=fail[pre]); if(str[pre+1]==str[i]) ++pre; fail[i]=pre,num[i]=num[pre]+1; } ll ans=1; pre=0; for(int i=1;i<=n;++i) { for(;pre&&str[pre+1]!=str[i];pre=fail[pre]); if(str[pre+1]==str[i]) ++pre; while(pre&&(pre<<1)>i) pre=fail[pre]; ans=ans*(num[pre]+1)%mod; } printf("%lld\n",ans); } int main() { // setI("input"); int T; scanf("%d",&T); for(int i=1;i<=T;++i) solve(); return 0; }