BZOJ 3670 && BZOJ 3620 && BZOJ 3942 KMP

Posted on 2016-07-04 20:06  yyjxx2010xyu  阅读(211)  评论(0编辑  收藏  举报

最近感到KMP不会啊,以前都是背板的现在要理解了。

 

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 const int Maxn=16000;
 7  
 8 char S[Maxn];
 9 int k,P[Maxn],Ans;
10  
11  
12 inline void Kmp(char * Str)
13 {
14     int j=0;
15     for (int i=2;Str[i];i++)
16     {
17         while (Str[j+1]!=Str[i] && j) j=P[j];
18         if (Str[j+1]==Str[i]) j++;
19         P[i]=j;
20     }
21     j=0;
22     for (int i=1;Str[i];i++)
23     {
24         while (Str[j+1]!=Str[i] && j) j=P[j];
25         if (Str[j+1]==Str[i]) j++;
26         while (j<<1>=i) j=P[j];
27         if (j>=k) Ans++;
28     }
29 }
30 int main()
31 {
32     scanf("%s",S+1);
33     scanf("%d",&k);     Ans=0;
34     for (int i=0;S[i+1];i++) Kmp(S+i);
35     printf("%d\n",Ans);
36     return 0;
37 }
38 
BZOJ 3620

其实这就是KMP的P数组的含义,即S[1~P[i]]==S[i-P[i]+1~i],但是题目中要求的的书不能重复,这样就要暴力找一下P[P[i]]就可以完成了。N^2暴力就可以过

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #define LL long long
 6 using namespace std;
 7 const LL Maxn=1000100;
 8 const LL Mod=1000000007;
 9 char S[Maxn];
10 LL k,P[Maxn],Ans,Cnt[Maxn],Kase;
11  
12  
13 inline void Kmp(char * Str)
14 {
15     LL j=0;
16     Cnt[1]=1;
17     for (LL i=2;Str[i];i++)
18     {
19         while (Str[j+1]!=Str[i] && j) j=P[j];
20         if (Str[j+1]==Str[i]) j++;
21         P[i]=j;
22         Cnt[i]=Cnt[j]+1;
23     }
24      
25     j=0; LL Ret;
26     for (LL i=2;Str[i];i++)
27     {
28         while (Str[j+1]!=Str[i] && j) j=P[j];
29         if (Str[j+1]==Str[i]) j++;
30         while (j<<1>i) j=P[j];
31         Ans=(Ans*(Cnt[j]+1))%Mod;
32     }
33 }
34 int main()
35 {
36     scanf("%lld",&Kase);
37     for (LL kase=1;kase<=Kase;kase++)
38     {
39         scanf("%s",S+1);
40         Ans=1; Kmp(S);
41         printf("%lld\n",Ans);
42     }
43     return 0;
44 }
45 
BZOJ 3670

其实和上一道是一样的。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int Maxn=1001000;
 8 char S[Maxn],T[Maxn],Stack[Maxn];
 9 int Lens,Lent,P[Maxn],top,a[Maxn];
10 int main()
11 {
12     scanf("%s",S+1);
13     scanf("%s",T+1);
14     Lens=strlen(S+1),Lent=strlen(T+1);
15     int j=0;
16     for (int i=2;i<=Lent;i++)
17     {
18         while (T[j+1]!=T[i] && j) j=P[j];
19         if (T[j+1]==T[i]) j++;
20         P[i]=j;
21     }
22     j=0;
23     for (int i=1;i<=Lens;i++)
24     {
25         j=a[top]; Stack[++top]=S[i];
26         while (T[j+1]!=Stack[top] && j) j=P[j];
27         if (T[j+1]==Stack[top]) j++;
28         a[top]=j;
29         if (j==Lent) top-=Lent;
30     }
31     for (int i=1;i<=top;i++) putchar(Stack[i]);
32     putchar('\n');
33     return 0;
34 }
35 
BZOJ 3942

裸的KMP..