描述


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

输入

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

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

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

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

输出

回文子串的数量

样例输入

abbab

样例输出

8

题解


利用Manacher,可以得到每个回文中心和其半径,不用去重,直接统计就好

#include <bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define PI acos(-1)
#define bug puts("here")
#define REP(i,x,n) for(int i=x;i<=n;i++)
#define DEP(i,n,x) for(int i=n;i>=x;i--)
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int N=800000+10;
char s[N],str[N*4];
int p[N*4],len1,len2;
void init(){
len1=strlen(s);
str[0]='(';
str[1]='#';
for(int i=0;i<len1;i++){
str[i*2+2]=s[i];
str[i*2+3]='#';
}
len2=len1*2+2;
str[len2]=')';
}
void Manacher(){
memset(p,0,sizeof(p));
int id=0,mx=0;
ll ans=0;
for(int i=1;i<len2;i++){
if(mx>i) p[i]=min(mx-i,p[2*id-i]);
else p[i]=1;
for(;str[i+p[i]]==str[i-p[i]];p[i]++);
if(p[i]+i>mx){
mx=p[i]+i;
id=i;
}
ans+=p[i]/2;
}
printf("%lld\n",ans);
}
int main(){
scanf("%s",s);
init();
Manacher();
return 0;
}

最新文章

  1. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》
  2. Consul 服务发现和配置
  3. C++联合
  4. web开发的步骤
  5. 转载:奇异值分解(SVD) --- 线性变换几何意义(上)
  6. 【Zend Studio】10.6.0版本设置默认编码为UTF-8
  7. 在SQL SErver中实现数组功能
  8. jquery 分页控件(一)
  9. vue原来可以这样上手
  10. mysql用户权限配置
  11. mysq基础操作
  12. BZOJ3864: Hero meet devil(dp套dp)
  13. jquery中val属性操作
  14. 协程greenlet、gevent
  15. Java语法基础学习DayEighteen(常用类)
  16. vc++调用exe获取输出信息
  17. _ViewStart文件应用
  18. 学习Spring Boot:(十)使用hibernate validation完成数据后端校验
  19. 引用EChart和Bootstrap
  20. [转]基本Guava工具

热门文章

  1. spoolight on oracle 配置
  2. 牛客网Java刷题知识点之为什么static成员方法不能是抽象方法,其必须实现
  3. AJPFX关于ArrayList集合容器的操作
  4. 总结一下WindowListener的用法
  5. [20190618]日常学习记录(二)-flex属性及vue实战
  6. UVA 11491 Erasing and Winning 奖品的价值 (贪心)
  7. idea存留
  8. 在DataGridView控件中隔行换色
  9. VC-基础:vs2010快捷键
  10. 安装 Win7 的系统的时候如何分区