2015 UESTC Training for Search Algorithm & String - J - 全都是秋实大哥 【KMP】

给出一个字符串,求每个前缀的最小循环节长度,并输出整个字符串的最小循环节。字符串长度为3*10^6

 

 

找循环节这种问题还是要用KMP
对于长度为i的字符串 i%(i-f[i])==0 此时,它的最小循环节长度就是i-f[i],f[i]是字符串的第i位的失配函数(注意是从1开始算)

 

#include<bits/stdc++.h>

#define eps 1e-9

#define FOR(i,j,k) for(int i=j;i<=k;i++)

#define MAXN 1005

#define MAXM 40005

#define INF 0x3fffffff

#define PB push_back

#define MP make_pair

#define X first

#define Y second

#define lc (k<<1)

#define rc ((k<<1)1)

using namespace std;

typedef long long LL;

int i,j,k,n,m,x,y,T,ans,big,cas,num,len;

bool flag;

char s[3000005];

int f[3000005];



void getFail(char *s,int *f)

{

    int m=strlen(s),j;

    f[0]=0;f[1]=0;

    for (int i=1;i<m;i++)

    {

        j=f[i];

        while (j&&s[i]!=s[j]) j=f[j];

        f[i+1]=(s[i]==s[j]?j+1:0);

    }

}



int main()

{

    scanf("%s",s);

    getFail(s,f);

    len=strlen(s);

     for (i=1;i<=len;i++)

     {

        if (i%(i-f[i])==0)

        {

            printf("%d ",i-f[i]);

        }else

        printf("%d ",i);

     }

     printf("\t\n");

     printf("%s\n",s+f[len]);

    return 0;

}

 

你可能感兴趣的:(Algorithm)