题意:

找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串

输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数

题解:

(回文自动机和回文树是一个东西)

首先用回文自动机求出所有本质不同的字符串,以及它们出现的次数,把前半部分的字符串和后半部分的字符串分别hash一遍,看他们是不是相等。

构造好回文自动机后,在回文自动机上dfs,向下传递当前字符串长度,正向,反向hash值,每次递归因为只增加了一个字母,所以可以O(1)计算。

#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 ;
}

hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash的更多相关文章

  1. [2019杭电多校第二场][hdu6599]I Love Palindrome String(回文自动机&&hash)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6599 题目大意为求字符串S有多少个子串S[l,r]满足回文串的定义,并且S[l,(l+r)/2]也满足 ...

  2. HDU-6599 I Love Palindrome String(回文自动机+字符串hash)

    题目链接 题意:给定一个字符串\(|S|\le 3\times 10^5\) 对于每个 \(i\in [1,|S|]\) 求有多少子串\(s_ls_{l+1}\cdots s_r\)满足下面条件 \( ...

  3. hdu 6053: TrickGCD (2017 多校第二场 1009) 【莫比乌斯 容斥原理】

    题目链接 定义f[n]表示n是最大公约数情况下的计数,F[n]为n是公约数情况下的计数 (可以和 http://www.cnblogs.com/Just--Do--It/p/7197788.html  ...

  4. HDU6602 Longest Subarray hdu多校第二场 线段树

    HDU6602 Longest Subarray 线段树 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602 题意: 给你一段区间,让你求最长的区间使 ...

  5. hdu多校第二场1008(hdu6598) Harmonious Army 最小割

    题意: 一个军队有n人,你可以给他们每个人安排战士或者法师的职业,有m对人有组合技,组合技的信息是a,b,c,代表如果这两个人是两个战士,则组合技威力为a,一个战士一个法师,威力为b,其中b=a/4+ ...

  6. hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability

    题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ...

  7. hdu多校第二场1011 (hdu6601) Keen On Everything But Triangle 主席树

    题意: 给定一个数列,每次询问一个区间,问这个区间中的值可组成的周长最大的三角形的周长. 题解: 定理1:给定一些值,这些值中组成边长最大的三角形的三条边的大小排名一定是连续的. 证明:假如第k大,第 ...

  8. hdu多校第二场 1010 (hdu6600)Just Skip This Problem

    题意: 给你一个数x,允许你多次询问yi,然后回答你x xor yi 是否等于yi,询问尽量少的次数以保证能求出xi是几,求出这样询问次数最少的询问方案数. 结果mod1e6+3 题解: 队友赛时很快 ...

  9. 2019牛客暑期多校训练营(第六场)C - Palindrome Mouse (回文自动机)

    https://ac.nowcoder.com/acm/contest/886/C 题意: 给出一个串A , 集合S里面为A串的回文字串 , 现在在集合S里面找出多少对(a,b),b为a的字串 分析: ...

随机推荐

  1. JS Window对象 计时器setInterval() 在执行时,从载入页面后每隔指定的时间执行代码。

    计时器setInterval() 在执行时,从载入页面后每隔指定的时间执行代码. 语法: setInterval(代码,交互时间); 参数说明: 1. 代码:要调用的函数或要执行的代码串. 2. 交互 ...

  2. 1 新增硬盘挂载home文件夹。 2 修理扇区

    一 挂载新硬盘 主机磁盘容量不够大时,想新增一颗新磁盘的时候.并将磁盘全部分割成单一分割槽,且将该分割槽挂载到/home目录,你该怎么做呢? 1  安装硬盘. 2  磁盘分区. 3 格式化磁盘 4 将 ...

  3. struts2注解返回json

    Struts2使用注解方式返回Json数据 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Geek_Alex/article/details/788 ...

  4. 支付宝支付接口-运行支付宝demo

    运行deme 提供了 支付  查询 退款 交易关闭几个简单的接口demo 下载 https://docs.open.alipay.com/270/106291/ 转为mave项目 1.创建一个空的ma ...

  5. Codeforces 1140E DP

    题意:给你一个数组,如果数组中的某个位置是-1那就可以填1到m的数字中的一个,但是要遵守一个规则:不能出现长度为奇数回文的子串,问合法的填法有多少种? 思路:不出现长度为奇数的回文子串,只需不出现长度 ...

  6. Python 分布式锁

    1,数据一致性 当多个进程/线程对同一个共享资源读写,会因为资源的争夺而出现混乱,导致数据不一致. 如下图: 在数据库的原始数据是 d0,上图的处理流程如下: t1 时刻,有两个数据源的数据 d1,d ...

  7. leetcode-158周赛-5224-掷筛子模拟

    题目描述: 方法:动态规划O(6∗6∗n∗15) 递归: from functools import lru_cache class Solution: def dieSimulator(self, ...

  8. Go 转义字符

    Go 转义字符 package main import "fmt" func main() { fmt.Printf("Hello\tWorld!") } 本文 ...

  9. NX二次开发-NXOPEN_DimensionCollection遍历图纸上的所有标注尺寸

    NX11+VS2013 #include <NXOpen/Drawings_DrawingSheet.hxx> #include <NXOpen/Drawings_DrawingSh ...

  10. Windows路径操作API函数学习【转载】

    文章出自https://www.cnblogs.com/MakeView660/p/6644838.html 前言 在VC++开发过程中,经常需要用到一些路径操作,比如拼需要的文件路径,搜索路径中的内 ...