• luogu2375 动物园 (kmp)


    首先求出fail数组,如果没有不重叠的限制的话,我们可以在求fail的时候递推出个数cnt[i]=cnt[fail[i]]+1(这个cnt是算上自己本身==自己本身的)

    然后如果是要求不重叠的话,就是相当于一直跳fail,直到找到了一个长度不超过一半的fail,然后num[i]就是它

    但如果直接暴力跳肯定是不行的

    其实它跟求fail的时候是一样的,只要每次不重置那个指针,就把它当成在求fail一样往后匹配这一位,匹配完这一位再跳回到一半以下,就可以保证复杂度

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define ll long long int
     5 using namespace std;
     6 
     7 const int M=1e9+7,maxn=1000100;
     8 
     9 char s[maxn];
    10 int fail[maxn],fulcnt[maxn];
    11 int len;
    12 ll ans=1;
    13 
    14 void getfail(){
    15     int i,j,k;
    16     fulcnt[1]=1;
    17     for(i=2,j=0,k=0;i<=len;i++){
    18         while(j && s[j+1]!=s[i])  j=fail[j];
    19         while(k && s[k+1]!=s[i])  k=fail[k];
    20         if(s[j+1]==s[i]) j++;
    21         if(s[k+1]==s[i]) k++;
    22         fail[i]=j;
    23         fulcnt[i]=fulcnt[j]+1;
    24         while(k&&k>i/2) k=fail[k];
    25         ans=(ans*(fulcnt[k]+1))%M;
    26     }
    27 }
    28 
    29 int main(){
    30     int t;
    31     // freopen("testdata.in","r",stdin);
    32     scanf("%d",&t);
    33     for(;t;t--){
    34         ans=1;
    35         scanf("%s",s+1);
    36         len=strlen(s+1);
    37         memset(fail,0,sizeof(fail));
    38         memset(fulcnt,0,sizeof(fulcnt));
    39         getfail();
    40         printf("%lld
    ",ans);
    41     }
    42 }
  • 相关阅读:
    Qt 无边框窗体改变大小 完美实现
    深入Windows窗体原理及控件重绘技巧
    EF里Guid类型数据的自增长、时间戳和复杂类型的用法
    Entity Framework中的Identity map和Unit of Work模式
    使用SQLite数据库和Access数据库的一些经验总结
    实现Avl平衡树
    使用Ajax
    接口和类 反射的差异性
    Guacamole 介绍
    依赖注入(DI)和Ninject
  • 原文地址:https://www.cnblogs.com/Ressed/p/9703705.html
Copyright © 2020-2023  润新知