I Love Palindrome String

时间限制: 2 Sec  内存限制: 128 MB

题目描述

You are given a string S=s1s2..s|S| containing only lowercase English letters. For each integer i∈[1,|S|] , please output how many substrings slsl+1...srsatisfy the following conditions:
 ∙ r−l+1 equals to i.
 ∙ The substring slsl+1...sr is a palindrome string.
 ∙ slsl+1...s⌊(l+r)/2⌋ is a palindrome string too.
|S| denotes the length of string S.
A palindrome string is a sequence of characters which reads the same backward as forward, such as madam or racecar or abba. 

输入

There are multiple test cases.
Each case starts with a line containing a string S(1≤|S|≤3×105) containing only lowercase English letters.
It is guaranteed that the sum of |S| in all test cases is no larger than 4×106.

输出

For each test case, output one line containing |S| integers. Any two adjacent integers are separated by a space.

样例输入

abababa

样例输出

7 0 0 0 3 0 0

题意:求有多少个字符串为回文串,且它的前一半也是回文串。
回文树+马拉车。先用回文树求出全部的本质不一样(就是长度不一样,或者长度一样内容不一样)的字符串,然后用马拉车快速判断该串是不是符合题意。
#include<bits/stdc++.h>
using namespace std;
//https://www.xuebuyuan.com/3184341.html
const int MAXN = ;
const int N = ; int Palindromic_Length[MAXN*];
int ans[MAXN]; struct Palindromic_Tree
{
int nxt[MAXN][],f[MAXN],cnt[MAXN],num[MAXN],len[MAXN],c[MAXN],last,n,L; int l[MAXN],r[MAXN]; inline int newnode(int x)
{
for(register int i=; i<; ++i)
nxt[L][i]=;
cnt[L]=;
len[L]=x;
return L++;
}
void init()
{
L=;
newnode();
newnode(-);
last=;
n=;
c[n]=-;
f[]=;
}
inline int getf(int x)
{
while(c[n-len[x]-]!=c[n])
x=f[x];
return x;
}
inline void add(int x)
{
x-='a';
c[++n]=x;
int cur=getf(last);
if(!nxt[cur][x])
{
int now=newnode(len[cur]+); l[now]=n-len[cur]-;
r[now]=n; f[now]=nxt[getf(f[cur])][x];
nxt[cur][x]=now;
}
++cnt[last=nxt[cur][x]];
}
void count()
{
for(register int i=L-; i>=; --i)
cnt[f[i]]+=cnt[i];
} void getans()
{
count();
for(int i=;i<L;i++)
{
int l1=l[i],r1=r[i];
r1=(l1+r1)/; r1*=;
l1*=; int mid=(r1+l1)/; if(mid-Palindromic_Length[mid]+<=(l1))
{
ans[len[i]]+=cnt[i];
}
}
} } PT; string Manacher(string s)
{
/*改造字符串*/
string res="$#";
for(int i=; i<s.size(); ++i)
{
res+=s[i];
res+="#";
} /*数组*/
vector<int> P(res.size(),);
int mi=,right=; //mi为最大回文串对应的中心点,right为该回文串能达到的最右端的值
int maxLen=,maxPoint=; //maxLen为最大回文串的长度,maxPoint为记录中心点 for(int i=; i<res.size(); ++i)
{
P[i]=right>i ?min(P[*mi-i],right-i):; //关键句,文中对这句以详细讲解 while(res[i+P[i]]==res[i-P[i]])
++P[i]; if(right<i+P[i]) //超过之前的最右端,则改变中心点和对应的最右端
{
right=i+P[i];
mi=i;
} if(maxLen<P[i]) //更新最大回文串的长度,并记下此时的点
{
maxLen=P[i];
maxPoint=i;
}
Palindromic_Length[i]=P[i]-; // printf("%d %d %c\n",i,P[i]-1,res[i]); }
return s.substr((maxPoint-maxLen)/,maxLen-);
} Palindromic_Tree tree;
int main()
{
char s[MAXN]; while(scanf("%s",s)==)
{
string a(s);
tree.init(); int len=strlen(s);
for(int i=;i<len;i++)tree.add(s[i]),ans[i+]=;
Manacher(a);
tree.getans();
for(int i=;i<=len;i++)printf("%d%c",ans[i],i==len ? '\n' : ' ');
}
//for(int i=0;i<a.size();i++)tree.add(a[i]);
return ; }

最新文章

  1. 《Web 前端面试指南》1、JavaScript 闭包深入浅出
  2. Ubuntu常用命令之update-alternatives
  3. docker-9 supervisord 参考docker从入门到实战
  4. HDU 1880 魔咒词典(字符串哈希)
  5. Linux安装MySql.Data for mono
  6. C语言中执行到预编译
  7. Docker-2 的创建、启动、终止、删除、迁移等
  8. python: linux下安装redis
  9. ElasticSearch(ES)和solr的关系和区别
  10. SAP 通过屏幕字段查看透明表
  11. php的模板引擎
  12. 解决 git extensions 每次提交需要输入用户名和密码
  13. 读写锁的实现原理(pthread_rwlock_t)
  14. php数据分页显示基础
  15. BZOJ 4538: [Hnoi2016]网络 [整体二分]
  16. Java之Collections.emptyList()、emptySet()、emptyMap()的作用和好处以及要注意的地方
  17. Oracle转换函数
  18. android 组建添加透明度
  19. zabbix准备:nginx安装
  20. 通过([AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement.Read)] )在前台html页面调用cs方法

热门文章

  1. 一台电脑同时添加git和bitbucket两个网站的ssh key
  2. arguments介绍(二)
  3. 你知道的和不知道的sass
  4. JavaScript编程基础
  5. 19-11-13-Night-∠
  6. VS2012 TFS 解决计算机改名无法连接TFS的问题
  7. Attribute类的使用
  8. 10-2-点击生成10个div
  9. nulls_hlist原理 和 tcp连接查找
  10. Django项目:CMDB(服务器硬件资产自动采集系统)--07--06CMDB测试Linux系统采集硬件数据的命令02