HDU3746--KMP+最小循环节

来源:互联网 发布:java泛型里的? 编辑:程序博客网 时间:2024/06/06 00:07

最小循环节求法:

定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。

(1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。

(2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。

推荐一篇文章,里面有关于next的优化:http://blog.csdn.net/niushuai666/article/details/696551

代码:

#include<cstdio>#include<cstring>using namespace std;int t,next[100009],len;char a[100009];void getnext(){    int i=0;    next[i]=-1;    int j=-1;    while(i<len)    {        if(j==-1||a[i]==a[j])        {            i++;            j++;            next[i]=j;        }        else        {            j=next[j];        }    }}int main(){    scanf("%d",&t);    while(t--)    {        scanf("%s",&a);        memset(next,0,sizeof(next));        len=strlen(a);        getnext();        int cir=len-next[len];        if(cir!=len && len%cir==0)printf("0\n");        else printf("%d\n",cir-next[len]%cir);    }}