• BZOJ 3670 && BZOJ 3620 && BZOJ 3942 KMP


    最近感到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
    ",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
    ",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('
    ');
    33     return 0;
    34 }
    35 
    BZOJ 3942

    裸的KMP..

  • 相关阅读:
    [Linux] XShell 远程 Ubuntu 云主机,图形化界面打开Chrome
    [UI] 工具 & 框架
    你不知道的<input type="file">的小秘密
    vue3逻辑分离和页面快速展示数据
    vue中props参数的使用
    vue3.0中reactive的正确使用姿势
    CF986B Petr and Permutations(逆序对)
    洛谷P1972 [SDOI2009]HH的项链(莫队)44分做法
    2021牛客暑期多校训练营5 B. Boxes(概率期望)
    2021牛客暑期多校训练营5 K. King of Range(单调队列)详细题解
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5641563.html
Copyright © 2020-2023  润新知