文章

14

粉丝

0

获赞

16

访问

917

头像
周期字符串 kmp和数学小公式 题解:
P1622
发布于2026年2月26日 13:00
阅读数 18

#include
using namespace std;

int main()
{
	int N;
	string s2; cin >> N;
	for(int i = 1; i <= N; i ++)
	{
		cin >> s2; int len2 = s2.size();
		vector moshi(len2, 0);
		
		for(int i = 1; i < len2; i ++)
		{
			int j = moshi[i - 1];
			while(j > 0 && s2[i] != s2[j]) j = moshi[j - 1];
			if(s2[i] == s2[j]) j ++;
			moshi[i] = j;
		} //kmp模板
		
		int p = len2 - moshi[len2 - 1]; 如果是周期串,比如题目例子,最小前缀为长度减去moshi[len2 - 1],这里不好理解
		if(moshi[len2 - 1] % p == 0) cout << p;
		else cout << len2;
		if(i != N) cout << '\n' << '\n';
	}
	
}

下面是g大人给的三段解释
kmp是最长公共前缀和公共后缀相等,就是moshi[i]对应数值

假设字符串 s 是由某个长度为 p 的字符串重复得到的:
|---- p ----|---- p ----|---- p ----|

那说明:

  • 去掉最后一个周期块,剩下的前缀

  • 去掉第一个周期块,剩下的后缀

它们一定完全一样,长度是 n - p,所以:最长相等前后缀长度 L = n - p 反过来:p = n - L,这就是:int p = n - L;
HoHoHo 再验证一次:n = 6  L = 4  p = 6 - 4 = 2  而 "Ho" 的长度正好是 2 

那为什么还要判断 n % p == 0

反例:abcab

...
登录查看完整内容


登录后发布评论

1 条评论
liux662
2026年2月26日 13:05

抱歉字体乱七八糟懒得改了,感觉g大人给的这个解释挺好懂的

赞(0)
回复给: