Period

这道题可以想到用KMP来解决,根据定义,对于每一个i,S[1-Nxt[i]+1~i]=S[1~Nxt[i]],并且不存在更大的循环节

Nxt[i]数组表示以i结尾的非前缀串与自身的前缀能匹配的最大数,可以方便更新

主要性质:

  • 必要性:若循环元为len,当且仅S[1~i-len]=S[len+1~i]
  • 充分性:从S[1~i-len]与S[len+1~i]各取len个字符,则S[1~len]=S[len+1~2*len],并以此类推,可以得出循环节的结论

Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int nxt[N],n,cnt;
char a[N];
inline void pre(){
    nxt[1]=0;
    for(int i=2,j=0;i<=n;i++){
        while(j>0&&a[i]!=a[j+1])j=nxt[j];//不断寻找能够继续匹配的
        if(a[i]==a[j+1])++j;//继续更新
        nxt[i]=j; 
    }
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%s",&n, a+1);
        pre();
        printf("Test case #%d\n",++cnt);
        for(int i=1;i<=n;i++)
         if(i%(i-nxt[i])==0&&i/(i-nxt[i])>1)//注意特判要大于1的循环次数
          printf("%d %d\n",i,i/(i-nxt[i]));
        puts("");
    }
}

 

posted @ 2019-08-23 21:55  Coder_cjh  阅读(183)  评论(0编辑  收藏  举报