P2375 [NOI2014]动物园

秘籍之kmp阅读理解---2

这题的题面好像比上一题好理解一点点??但原谅我样例可能理解了半年。。。(其实后来发现luogu讨论里有对于样例的提问和解释,但是很开心的是,我并没有看到。。/微笑/)

这里对于一样不理解样例的人说一句,这里的num数组并不是存储最长的子串长度,而是满足条件的子串个数,嗯对

那经过我这半个小时对于样例的热切探讨,还是15分钟打了个板子,在预处理中加了个类似于递推的语句求解num的简化版数组,再通过kmp主函数中让读入的数组自己跟自己kmp(。。没有别的含义哦不要乱想。。),处理出num真正的数组

 1 #include<set>
 2 #include<map>
 3 #include<list>
 4 #include<queue>
 5 #include<stack>
 6 #include<string>
 7 #include<cmath>
 8 #include<ctime>
 9 #include<vector>
10 #include<bitset>
11 #include<memory>
12 #include<utility>
13 #include<cstdio>
14 #include<sstream>
15 #include<iostream>
16 #include<cstdlib>
17 #include<cstring>
18 #include<algorithm>
19 using namespace std;
20 const int mod=1000000007;
21 
22 int n,lzy;
23 long long zz,z,y;
24 int next[1000005],num[1000005];
25 char zy[1000005];
26 
27 inline long long ma(long long a,int b){return a>b?a:b;}//手写min max函数快一丢丢
28 
29 void advance(){//预处理(这个单词我昨天晚上现场百度的emmmmm)
30     next[0]=-1;//赋初值
31     next[1]=0;
32     num[1]=1;
33     for(int i=1,j=0;i<lzy;i++){
34         while(j&&zy[i]!=zy[j]){
35             j=next[j];
36         }
37         if(zy[i]==zy[j]){
38             j++;
39         }
40         next[i+1]=j;
41         num[i+1]=num[j]+1;//处理出伪num数组
42     }
43 }
44 
45 void KMP(){//kmp
46     for(int i=1,j=0;i<lzy;i++) {
47         while(j>=0&&zy[i]!=zy[j]){
48             j=next[j];
49         }
50         j++;
51         while((j*2)>(i+1)){//若子串过长,则缩短
52             j=next[j];
53         }
54         y*=(long long)(num[j]+1);//强制转换longlong
55         y%=mod;//取模
56     }
57 }
58 
59 int main(){
60     scanf("%d",&n);
61     while(n--){
62         cin>>zy;
63         lzy=strlen(zy);
64         z=0;
65         y=1;
66         advance();
67         KMP();
68         printf("%lld\n",y);//记得要用longlong
69     }
70     return 0;
71 }

lalala睡觉了,白白

哦对了原谅我就写了三题,那是因为我tm昨天晚上脑子都要炸了。。kmp本身就不好理解,还tm变着花玩???我丢告辞!!

上一篇:[NOI2014] 随机数生成器


下一篇:[NOI2014]购票——斜率优化+树链剖分+线段树