【題目大意】
[依然借用別人的歸納]給定一個長爲L的字符串(L<=100W),求一個num數組,num[i]表示長度爲i的前綴中字符串S’的數量,其中S‘既是該前綴的前綴也是該前綴的後綴,且|S'|*2<=i
【思路】
KMP中next數組的變形。先算一次next數組和dep數組,其中dep數組表示當前前綴通過j=next[j]能夠到達-1,這個值其實就是num數組的雛形。而後再進行一次求解next數組,每次前綴不斷進行j=next[j],直到知足|S'|*2<=i。此時的dep[j]就是當前前綴的num值,因爲前一次求解next數組預處理,這個值能夠在O(1)時間內求解。ios
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define LL long long 6 #define mod 1000000007 7 const int MAXN=1000000+500; 8 using namespace std; 9 int n; 10 char p[MAXN]; 11 int next[MAXN],dep[MAXN],next2[MAXN]; 12 int len; 13 14 void getnext() 15 { 16 int i=0,j=-1; 17 next[i]=j; 18 dep[i]=0; 19 while (i<len) 20 { 21 if (j==-1 || p[i]==p[j]) 22 { 23 dep[++i]=dep[++j]+1; 24 next[i]=j; 25 } 26 else j=next[j]; 27 } 28 } 29 30 void getans() 31 { 32 LL ans=1; 33 int i=0,j=-1; 34 while (i<len) 35 { 36 if (j==-1 || p[i]==p[j]) 37 { 38 i++,j++; 39 while (j!=-1 && (j<<1)>i) 40 j=next[j]; 41 if (j!=-1 && i!=-1) ans=ans*(LL)(dep[j]+1) % mod; 42 } 43 else j=next[j]; 44 } 45 printf("%lld\n",ans); 46 47 48 } 49 50 int main() 51 { 52 scanf("%d",&n); 53 for (int i=0;i<n;i++) 54 { 55 scanf("%s",p); 56 len=strlen(p); 57 getnext(); 58 getans(); 59 } 60 return 0; 61 }