http://poj.org/problem?id=2406

题意:给定一个字符串 L,已知这个字符串是由某个字符串 S 重复 R 次而得到的,求 R 的最大值。(长度<=1000000)

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <iostream>
  6. using namespace std;
  7. int p[2000000];
  8. char s[2000000];
  9. int main() {
  10. while(scanf("%s", s+1), s[1]!='.') {
  11. int j=0, n=strlen(s+1); p[1]=0;
  12. for(int i=2; i<=n; ++i) {
  13. while(j && s[j+1]!=s[i]) j=p[j];
  14. if(s[j+1]==s[i]) ++j;
  15. p[i]=j;
  16. }
  17. if(n%(n-p[n])==0) printf("%d\n", n/(n-p[n]));
  18. else puts("1");
  19. }
  20. return 0;
  21. }

kmp求出next后那么最短循环串的长度为n-next[n],只需要判断n是否整除它即可。

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <cmath>
  5. using namespace std;
  6.  
  7. const int N=2000005;
  8. inline void sort(int *x, int *y, int *sa, int n, int m) {
  9. static int c[N], i;
  10. for(i=0; i<m; ++i) c[i]=0;
  11. for(i=0; i<n; ++i) ++c[x[y[i]]];
  12. for(i=1; i<m; ++i) c[i]+=c[i-1];
  13. for(i=n-1; i>=0; --i) sa[--c[x[y[i]]]]=y[i];
  14. }
  15. inline void hz(int *a, int *sa, int n, int m) {
  16. static int t1[N], t2[N], i, j, p, *x, *y, *t;
  17. x=t1, y=t2;
  18. for(i=0; i<n; ++i) x[i]=a[i], y[i]=i;
  19. sort(x, y, sa, n, m);
  20. for(j=1, p=1; p<n; j<<=1, m=p) {
  21. p=0;
  22. for(i=n-j; i<n; ++i) y[p++]=i;
  23. for(i=0; i<n; ++i) if(sa[i]-j>=0) y[p++]=sa[i]-j;
  24. sort(x, y, sa, n, m);
  25. for(t=x, x=y, y=t, p=1, x[sa[0]]=0, i=1; i<n; ++i)
  26. x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+j]==y[sa[i-1]+j]?p-1:p++;
  27. }
  28. }
  29. inline void geth(int *s, int *sa, int *rank, int *h, int n) {
  30. static int j, i, k;
  31. for(i=1; i<=n; ++i) rank[sa[i]]=i;
  32. for(k=0, i=1; i<=n; h[rank[i++]]=k)
  33. for(k?--k:0, j=sa[rank[i]-1]; s[i+k]==s[j+k]; ++k);
  34. }
  35.  
  36. int a[N], sa[N], h[N], rank[N], n;
  37. char s[N];
  38. inline int work() {
  39. static int len[N], pos;
  40. pos=rank[1];
  41. for(int i=pos, mn=h[i]; i>1; --i) mn=min(h[i], mn), len[i-1]=mn;
  42. for(int i=pos+1, mn=h[i]; i<=n; ++i) mn=min(h[i], mn), len[i]=mn;
  43. int sq=sqrt(n+0.5);
  44. for(int k=1; k<=sq; ++k) if(n%k==0 && len[rank[k+1]]==n-k) return n/k;
  45. return 1;
  46. }
  47. int main() {
  48. while(scanf("%s", s+1), s[1]!='.') {
  49. n=strlen(s+1);
  50. for(int i=1; i<=n; ++i) a[i]=s[i];
  51. a[0]=0;
  52. hz(a, sa, n+1, 255);
  53. geth(a, sa, rank, h, n);
  54. printf("%d\n", work());
  55. }
  56. return 0;
  57. }

  


经典题...可是我tle了......因为本题听说是用kmp.............QAQ

sa的做法就是,求出height后,我们只匹配suffix(1)和suffix(k+1)的最长公共前缀是否为n-k即可,k是枚举的长度...至于为什么,请自己想...

【POJ】2406 Power Strings的更多相关文章

  1. POJ——T 2406 Power Strings

    http://poj.org/problem?id=2406 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 50627   ...

  2. 【POJ】3134 Power Calculus

    1. 题目描述给定一个正整数$n$,求经过多少次乘法或除法运算可以从$x$得到$x^n$?中间结果也是可以复用的. 2. 基本思路实际结果其实非常小,肯定不会超过20.因此,可以采用IDA*算法.注意 ...

  3. poj 2406 Power Strings (kmp 中 next 数组的应用||后缀数组)

    http://poj.org/problem?id=2406 Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submiss ...

  4. poj 2406 Power Strings 后缀数组解法

    连续重复子串问题 poj 2406 Power Strings http://poj.org/problem?id=2406 问一个串能否写成a^n次方这种形式. 虽然这题用kmp做比较合适,但是我们 ...

  5. KMP POJ 2406 Power Strings

    题目传送门 /* 题意:一个串有字串重复n次产生,求最大的n KMP:nex[]的性质应用,感觉对nex加深了理解 */ /************************************** ...

  6. POJ 2406 Power Strings (KMP)

    Power Strings Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 29663Accepted: 12387 Descrip ...

  7. 【POJ】1704 Georgia and Bob(Staircase Nim)

    Description Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, ...

  8. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

  9. 【kmp+最小循环节】poj 2406 Power Strings

    http://poj.org/problem?id=2406 [题意] 给定字符串s,s=a^n,a是s的子串,求n最大是多少 [思路] kmp中的next数组求最小循环节的应用 例如 ababab ...

随机推荐

  1. C 结构体小结

    看了三天结构体,是时候总结一下了. 关于结构体的声明: struct Student { ]; char sex; int age; ]; }; /*然后定义一个Student 类型的 student ...

  2. 已知局域网IP地址,如何查看mac

    arp -a 加对方IP是查对方的MAC地址 转自: http://zhidao.baidu.com/link?url=8sRdpGcjfGQ-C1F9zNub49Mxe3DAR-RCAHDkHvKC ...

  3. 1.1 让CPU占用率曲线听你指挥[cpu manager]

    [本文链接] http://www.cnblogs.com/hellogiser/p/cpu-manager.html [题目] 写一个程序,让用户来决定Windows任务管理器(Task Manag ...

  4. mysql 基于lvm快照的备份

    1.查看磁盘数 ls /dev/ | grep sd 2.快照备份 pvcreate /dev/sdb #制作成物理卷vgcreate testvg /dev/sdblvcreate -L200M - ...

  5. 【QT】ui转代码

    windows中安装qt目录下的BIN文件夹里有个uic.exe把UIC.exe和你要转换的xxx.ui文件拷贝到同一目录.开始菜单,运行CMD,命令进入uic.exe和xxx.ui的目录,(或在存放 ...

  6. Gym 100801E Easy Arithmetic (思维题)

    题目:传送门.(需要下载PDF) 题意:给定一个长度不超过1000的字符串表达式,向该表达式中加入'+'或'-',使得表达式的值最大,输出该表达式. 题解:比如300-456就改成300-4+56,遇 ...

  7. WampServer phpadmin apache You don't have permission to access

    1.Forbidden You don't have permission to access / on this server. 后来咨询了一下朋友(php高手),说修改一下php的配置文件http ...

  8. 堆的判断(codevs 2879)

    2879 堆的判断  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 堆是一种常用的数据结构.二叉堆 ...

  9. icon上添加数字提醒

    使用viewbadger包: package com.jingle.vierbagerstudy; import android.app.Activity; import android.os.Bun ...

  10. Android实现支持缩放平移图片

    本文主要用到了以下知识点 Matrix GestureDetector 能够捕捉到长按.双击 ScaleGestureDetector 用于检测缩放的手势 自由的缩放 需求:当图片加载时,将图片在屏幕 ...