BZOJ 3670 && BZOJ 3620 && BZOJ 3942 KMP
Posted on 2016-07-04 20:06 yyjxx2010xyu 阅读(215) 评论(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
其实这就是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
其实和上一道是一样的。
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
裸的KMP..