#P5638. period题解

题目描述

给定一个长度为 NN 的字符串 SS,其中 2≤N≤1062≤N≤106。

定义 Pi=S[1..i]Pi​=S[1..i],即字符串 SS 的前 ii 个字符组成的前缀。对于某些 PiPi​,如果它可以表示为某个字符串重复 KK 次(K>1K>1 且 KK 尽可能大)的形式,则输出对应的 ii 和 KK。

输入格式

多组测试数据。

每组数据第一行包含一个整数,表示字符串的长度 NN。第二行包含一个长度为 NN 的字符串 SS。

输入以 00 表示结束。

输出格式

对于每组测试数据,首先输出一行 Test case #X,其中 XX 表示当前是第几组测试数据(从 11 开始编号)。然后按顺序输出所有满足条件的 ii 和 KK,每对 ii 和 KK 占一行。

输入数据 1

3
aaa
12
aabaabaabaab
0

输出数据 1

Test case #1
2 2
3 3

Test case #2
2 2
6 2
9 3
12 4

解释:

  • 对于第一组数据,字符串为 aaa

    • 前缀 P2="aa"P2​="aa" 可以表示为 "a""a" 重复 22 次;
    • 前缀 P3="aaa"P3​="aaa" 可以表示为 "a""a" 重复 33 次。
  • 对于第二组数据,字符串为 aabaabaabaab

    • 前缀 P2="aa"P2​="aa" 可以表示为 "a""a" 重复 22 次;
    • 前缀 P6="aabaab"P6​="aabaab" 可以表示为 "aab""aab" 重复 22 次;
    • 前缀 P9="aabaabaab"P9​="aabaabaab" 可以表示为 "aab""aab" 重复 33 次;
    • 前缀 P12="aabaabaabaab"P12​="aabaabaabaab" 可以表示为 "aab""aab" 重复 44 次。

思路

kmp

代码见下

#include<bits/stdc++.h>
using namespace std;
long long t,kmp[10000006],as,bs,op=0,db=0,w=0;
char a[10000006],b[10000006];
int main(){
    while(cin>>t){
        if(t==0){
            break;
        }
        cin>>b+1;
        db=1;
        bs=strlen(b+1);
        w++;
        cout<<"Test case #"<<w<<endl;
                for(int i=2,j=0;i<=bs;i++){
                    while(j!=0&&b[i]!=b[j+1]){
                        j=kmp[j];
                    }
                    if(b[j+1]==b[i]){
                        j++;
                    }
                    kmp[i]=j;
                }
                for(int i=0;i<=bs;i++){
                    b[i]=' ';
                }
                for(int i=2;i<=bs;i++){
                    if(i%(i-kmp[i])==0&&i/(i-kmp[i])>=2){
                        cout<<i<<" "<<i/(i-kmp[i])<<endl;
                    }                    
                }
    }

	return 0;
} 

posted @ 2025-11-11 21:27  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源