Hdu 1358 Period(KMP Next数组的理解)

喜欢ヅ旅行 2022-05-19 07:06 322阅读 0赞

传送门

题意:给你一个长度为n的(2 <= N <= 1 000 000)字符串,求字符串的所有前缀字符串中字能刚好由k(k>1)个循环节构成的字符串,输出这些k。

分析:由于题目要求k最大,那么其实就是求最小循环节,由于N很大很明显我们不能用暴力解决,我们想到Next数组其实是存了每个子串的前后缀匹配信息的,以i结尾的字符串它的最小循环节minPeriod的长度其实就是 i-Next[i] ,所以我们只需要i从小到大扫一遍如果当前 i 能够整除最小循环节,就说明这个子串能够由最小循环节通过循环组成,那么就输出最小循环节循环的次数。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 1e6+5;
  4. char t[maxn];
  5. int Next[maxn];
  6. int N;
  7. void getNext()
  8. {
  9. int j = -1,i = 0;
  10. Next[0] = -1;
  11. while(i<N)
  12. {
  13. if(j==-1||t[i]==t[j])
  14. {
  15. ++i;
  16. ++j;
  17. Next[i]=j;
  18. }
  19. else j = Next[j];
  20. }
  21. }
  22. int main()
  23. {
  24. int kase = 0;
  25. while(scanf("%d",&N)&&N)
  26. {
  27. scanf("%s",t);
  28. getNext();
  29. printf("Test case #%d\n",++kase);
  30. for(int i=2;i<=N;i++)
  31. {
  32. int minPeriod=i-Next[i];
  33. if(i%minPeriod==0&&i/minPeriod!=1)/**题目要求中 K>1*/
  34. {
  35. printf("%d %d\n",i,i/minPeriod);
  36. }
  37. }
  38. printf("\n");
  39. }
  40. return 0;
  41. }

发表评论

表情:
评论列表 (有 0 条评论,322人围观)

还没有评论,来说两句吧...

相关阅读

    相关 HDU 1358(kmp)

    题意:给出一个数字n,接下来一行是一个字符串,n是这个字符串的长度。求这个字符串的所有是循环字符串的前缀。 kmp中的next数组只得是第i个字符匹配错误,向前跳的位置nex