当前位置:   article > 正文

hihocoder#1589 : 回文子串的数量(manacher)_manacher hash 回文数

manacher hash 回文数

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

给定一个字符串S,请统计S的所有|S| * (|S| + 1) / 2个子串中(首尾位置不同就算作不同的子串),有多少个是回文字符串?

输入

一个只包含小写字母的字符串S。

对于30%的数据,S长度不超过100。

对于60%的数据,S长度不超过1000。

对于100%的数据,S长度不超过800000。

输出

回文子串的数量

样例输入
abbab
样例输出
8
思路:manacher算法模版题。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int MAX=2e6;
  4. char p[MAX],s[MAX];
  5. int len[MAX];
  6. int init(char *str)
  7. {
  8. int n=strlen(str);
  9. for(int i=1,j=0;i<=2*n;j++,i+=2)
  10. {
  11. s[i]='#';
  12. s[i+1]=str[j];
  13. }
  14. s[0]='$';
  15. s[2*n+1]='#';
  16. s[2*n+2]='@';
  17. s[2*n+3]='\n';
  18. return 2*n+1;
  19. }
  20. void manacher(int n)
  21. {
  22. int mx=0,p=0;
  23. for(int i=1;i<=n;i++)
  24. {
  25. if(mx>i)len[i]=min(mx-i,len[2*p-i]);
  26. else len[i]=1;
  27. while(s[i-len[i]]==s[i+len[i]])len[i]++;
  28. if(len[i]+i>mx)mx=len[i]+i,p=i;
  29. }
  30. }
  31. int main()
  32. {
  33. scanf("%s",p);
  34. int n=init(p);
  35. memset(len,0,sizeof len);
  36. manacher(n);
  37. long long ans=0;
  38. for(int i=1;i<=n;i++)ans+=len[i]/2;
  39. cout<<ans<<endl;
  40. return 0;
  41. }




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/799658
推荐阅读
相关标签
  

闽ICP备14008679号