记录编号 428328 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [51nod 1129] 字符串最大值 最终得分 100
用户昵称 GravatarCSU_Turkey 是否通过 通过
代码语言 C++ 运行时间 0.102 s
提交时间 2017-07-25 13:27:35 内存使用 8.90 MiB
显示代码纯文本
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int f[1000005],g[1000005];
  4. char a[1000005];
  5. int main()
  6. {
  7. freopen("string_maxval.in","r",stdin);
  8. freopen("string_maxval.out","w",stdout);
  9. scanf("%s",a);
  10. int lena=strlen(a);
  11. for(int i=lena;i>=1;i--)
  12. a[i]=a[i-1];
  13. for(int i=2;i<=lena;i++)
  14. {
  15. int j=f[i-1];
  16. while(j&&a[j+1]!=a[i])
  17. j=f[j];
  18. if(a[j+1]==a[i])
  19. f[i]=j+1;
  20. else
  21. f[i]=0;
  22. }
  23. for(int i=1;i<=lena;i++)
  24. g[i]=1;
  25. int ma=-1;
  26. for(int i=lena;i>=1;i--)
  27. {
  28. g[f[i]]+=g[i];
  29. ma=max(ma,i*g[i]);
  30. }
  31. cout<<ma;
  32. return 0;
  33. }
  34. /*
  35. 递推式昨天还会今天突然就不会了....屡了半天,大概知道了吧,一个串每出现一次,
  36. 你的最长前缀就多出现一次(递推式初始全是1表示从第一位开始的那个(不是加2不然这个会被重复计算))
  37. 至于前缀的前缀,我们乍一看,应该加3次,但只加了2次,是不是就有错呢?事实上是没有的,我们可以
  38. 模拟一下这个过程,(ababababcabababababab),(我连自己都说服不了..)往前找的时候
  39. 会出现一种情况,(恰好是当时的前缀去掉除其前缀以外的剩余字母(只不过发生在字符串尾部而不是前面))
  40. 当时前缀的前缀成了现在的前缀,会给他加上那缺少的一次,如果像我给的样例那样
  41. 到达那个位置的时候前缀并不是当时前缀的前缀,也就不会给他加,那该怎么办,我们会发现一直找下去总会有
  42. 我所说的那种情况出现,而中间都是重复的(前缀的前缀重复使用(在相邻两个"前缀“中分别充当前缀和后缀)),
  43. 所以不需要额外加;
  44. */