1. 程式人生 > >[NOI2014]

[NOI2014]

求值 sig net 重新 一半 log name color max

OJ題號:洛谷2375、BZOJ3670

思路:

一開始先寫了一個裸的KMP,在求next數組(f數組)的時候加了一個判斷j<<1是否>i+1(若大於則說明有重疊部分),後來發現並不能這樣做。因為這樣會影響到後面next數組的求值。後來看了一個題解,裏面的思路是重新做一遍求next的過程,同時再判斷是否超過一半。同時引入了num數組的概念,不過比較難理解,畢竟KMP整個才剛剛有點思緒。 參考:http://blog.csdn.net/zhaoyh2000/article/details/54866734

 1 #define maxl 1000000+1
 2 #define mod 1000000007
 3
#include<string> 4 #include<iostream> 5 using namespace std; 6 int n,f[maxl],num[maxl]; 7 string s; 8 int main() { 9 ios::sync_with_stdio(false); 10 cin>>n; 11 while(n--) { 12 cin>>s; 13 f[0]=-1; 14 f[1]=0; 15 num[0]=0
; 16 num[1]=1; 17 int j=0; 18 unsigned long long ans=1ull; 19 for(int i=1;i<(int)s.length();i++) { 20 while(j>=0&&s[i]!=s[j]) j=f[j]; 21 f[i+1]=++j; 22 num[i+1]=num[j]+1; 23 } 24 j=0; 25 for
(int i=1;i<(int)s.length();i++) { 26 while(j>=0&&s[i]!=s[j]) j=f[j]; 27 j++; 28 while((j<<1)>(i+1)) j=f[j]; 29 ans*=(unsigned long long)num[j]+1; 30 ans%=mod; 31 } 32 cout<<ans<<endl; 33 } 34 return 0; 35 }

[NOI2014]