题意:

求有多少个回文串的前⌈len/2⌉个字符也是回文串。(两组解可重复)
将这些回文串按长度分类,分别输出长度为1,2,...,n的合法串的数量。

题解:https://www.cnblogs.com/Cwolf9/p/11253106.html

我们使用回文自动机可以知道本质回文窜的个数与长度,我们在添加一个数组id[i], 记录第i个回文窜的结束位置就可以知道这个回文窜在原窜的区间[L,R];

我们在用字符串哈希就可以快速的判断前⌈len/2⌉个字符是不是回文了

,因为他本身是回文串,因此就是判断前后两部分是否相同

#include "bits/stdc++.h"

using namespace std;
const double eps = 1e-;
#define reg register
#define lowbit(x) x&-x
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fi first
#define se second
#define makp make_pair int dcmp(double x) {
if (fabs(x) < eps) return ;
return (x > ) ? : -;
} typedef long long ll;
typedef unsigned long long ull;
const ull hash1 = ;
const ull hash2 = ;
const int N = + ;
const int M = + ;
const int inf = 0x3f3f3f3f;
const ll mod = ;
ll ret[N];
ull ha[N], pp[N]; ull getha(int l, int r) {
if (l == ) return ha[r];
return ha[r] - ha[l - ] * pp[r - l + ];
} bool check(int l, int r) {
int len = r - l + ;
int mid = (l + r) >> ;
if (len & ) return getha(l, mid) == getha(mid, r);
else return getha(l, mid) == getha(mid + , r);
} struct Palindromic_Tree {
int nxt[N][], fail[N], cnt[N];
int num[N], len[N], s[N], id[N];
int last, n, p; int newnode(int l) {
memset(nxt[p], , sizeof(nxt[p]));
cnt[p] = num[p] = ;
len[p] = l;
return p++;
} void init() {
p = ;
newnode(), newnode(-);
last = n = ;
s[] = -;
fail[] = ;
} int get_fail(int x) {
while (s[n - len[x] - ] != s[n]) x = fail[x];
return x;
} void add(int c) {
c -= 'a';
s[++n] = c;
int cur = get_fail(last);
if (!nxt[cur][c]) {
int now = newnode(len[cur] + );
fail[now] = nxt[get_fail(fail[cur])][c];
nxt[cur][c] = now;
num[now] = num[fail[now]] + ;
}
last = nxt[cur][c];
cnt[last]++, id[last] = n;
} ll Count() {
for (int i = p - ; i >= ; i--) cnt[fail[i]] += cnt[i];
for (int i = ; i < p; i++) {
///cout << id[i] - len[i] << " " << id[i] - 1 << endl;
if (check(id[i] - len[i], id[i] - 1)) {
ret[len[i]] += cnt[i];
}
}
return ;
}
} pam; char str[N]; int main() {
pp[] = ;
for (int i = ; i < N; i++) {
pp[i] = hash1 * pp[i - ];
}
while (~scanf("%s", str)) {
memset(ret, , sizeof(ret));
pam.init();
int len = strlen(str);
ha[] = str[];
for (int i = ; i < len; i++) {
pam.add(str[i]);
}
for (int i = ; i < len; i++) {
ha[i] = ha[i - ] * hash1 + str[i];
}
pam.Count();
printf("%lld", ret[]);
for (int i = ; i <= len; i++) {
printf(" %lld", ret[i]);
}
printf("\n");
}
return ;
}

最新文章

  1. 通过Laravel 初识Vue.js
  2. p4lang/switch make bm-switchsai 出现内存不足导致的Error
  3. ajax原理和跨域解决方法
  4. 【HDU 5698】瞬间移动(组合数,逆元)
  5. 优测优社区干货精选|老司机乱谈编辑器之神——vim
  6. 网址、URL
  7. 浅析NSTimer &amp; CADisplayLink内存泄露
  8. C程序设计语言练习题1-4
  9. Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
  10. js之promise讲解
  11. day10 while else continue break
  12. 利用httpd配置虚拟目录创建下载站点
  13. C#学习-属性是对字段的扩展
  14. 关于海康威视与Unity3d集成冲突问题解决
  15. 【Tomcat】压力测试和优化
  16. 9-9-B+树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版
  17. Vue学习【第二篇】:ES6简单介绍
  18. 【剑指offer】二进制中1的个数
  19. python3之模块urllib
  20. vue里ref ($refs)用法

热门文章

  1. Java - Java Mail邮件开发(3)spring +Java Mail + Velocity
  2. centos 7 无网络情况下,解决yum 安装依赖rpm包
  3. The kth great number
  4. Qfile
  5. [LeetCode] 84. 柱状图中最大的矩形
  6. 自己写的SqlHelper,提示在调用&quot;Fill&quot;前,SelectCommand 属性尚未初始化.错误
  7. POJ 3667 Hotel (线段树区间合并)
  8. 长沙理工大学第十二届ACM大赛-重现赛 J 武藏牌牛奶促销
  9. shell安装mysql,连接数据库,创建数据库
  10. Android工具集合