由样例可知,题目中求的回文串数量,其实是本质不同的回文串数量,这个可以直接用回文树来做。

考虑前半段是回文串这个限制,这个东西回文树不好做,可以再套一个马拉车,然后记录一下插入到回文树的节点中最后一个字符的位置,使用马拉车快速判断这一段的前半段是不是回文串

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define fd(i, l, r) for (int i = r; i >= l; i--)
#define mem(x) memset(x, 0, sizeof(x))
#define ll long long
using namespace std;
const int maxn = ;
ll read()
{
ll x = , f = ;
char ch = getchar();
while (!(ch >= '' && ch <= ''))
{
if (ch == '-')
f = -;
ch = getchar();
};
while (ch >= '' && ch <= '')
{
x = x * + (ch - '');
ch = getchar();
};
return x * f;
} char Ma[maxn * ];
int Mp[maxn * ];
void Manacher(char s[], int len)
{
int l = ;
Ma[l++] = '$';
Ma[l++] = '#';
for (int i = ; i < len; i++)
{
Ma[l++] = s[i];
Ma[l++] = '#';
}
Ma[l] = ;
int mx = , id = ;
for (int i = ; i < l; i++)
{
Mp[i] = mx > i ? min(Mp[ * id-i], mx-i) : ;
while (Ma[i + Mp[i]] == Ma[i-Mp[i]])
Mp[i]++;
if (i + Mp[i] > mx)
{
mx = i + Mp[i];
id = i;
}
}
} const int N = , S = ;
int all, son[N][S], fail[N], cnt[N], len[N], text[N], pos[N], last, tot;
int newnode(int l)
{
for (int i = ; i < S; i++)
son[tot][i] = ;
cnt[tot] = , len[tot] = l;
return tot++;
}
void init()
{
last = tot = all = ;
newnode(), newnode(-);
text[] = -, fail[] = ;
}
int getfail(int x)
{
while (text[all - len[x] - ] != text[all])
x = fail[x];
return x;
}
void add(int w,int p)
{
text[++all] = w;
int x = getfail(last);
if (!son[x][w])
{
int y = newnode(len[x] + );
fail[y] = son[getfail(fail[x])][w];
son[x][w] = y;
pos[y] = p;
}
cnt[last = son[x][w]]++;
}
void count()
{
for (int i = tot - ; ~i; i--)
cnt[fail[i]] += cnt[i];
}
char s[maxn];
int slen, s2[maxn];
ll ans[maxn];
int flag;
inline bool check(int l,int r){
int len = r-l+;
if(len==)return true;
r = (l+r)>>;
len = r-l+;
if(len&){
int t = l + (len>>);
t *= ;
return Mp[t]- >= len;
}else{
int t = l + (len >> );
t = t*-;
return Mp[t]- >= len;
}
}
void dfs(int u, int d)
{
fo(i, , )
{
if (son[u][i])
{
s2[d + ] = i;
dfs(son[u][i], d + );
}
}
if (d)
{
int lenu = d + d - flag;
int rp = pos[u];
int lp = pos[u]-lenu+;
if(check(lp,rp))ans[d + d - flag] += cnt[u];
}
}
int main()
{
int tt = ;
int T;
while (scanf("%s", s + ) != EOF)
{
init();
memset(ans, , sizeof(ans));
slen = strlen(s + );
fo(i, , slen)
{
add(s[i] - 'a',i);
}
count();
Manacher(s+,slen);
flag = ;
dfs(, );
flag = ;
dfs(, );
printf("%lld", ans[]);
fo(i, , slen)
{
printf(" %lld", ans[i]);
}
putchar('\n');
}
return ;
}

hdu6599 I Love Palindrome String的更多相关文章

  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. I Love Palindrome String

    I Love Palindrome String 时间限制: 2 Sec  内存限制: 128 MB 题目描述 You are given a string S=s1s2..s|S| containi ...

  4. 2019 Multi-University Training Contest 2 I.I Love Palindrome String(回文自动机+字符串hash)

    Problem Description You are given a string S=s1s2..s|S| containing only lowercase English letters. F ...

  5. hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash

    题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...

  6. I Love Palindrome String HDU - 6599 回文树+hash

    题意: 输出每个长度下的回文串(这些回文串的左半边也需要是回文串) 题解: 直接套上回文树,然后每找到一个回文串就将他hash. 因为符合要求的回文串本身是回文串,左半边也是回文串,所以它左半边也右半 ...

  7. HDU 6599 I Love Palindrome String (回文树+hash)

    题意 找如下子串的个数: (l,r)是回文串,并且(l,(l+r)/2)也是回文串 思路 本来写了个回文树+dfs+hash,由于用了map所以T了 后来发现既然该子串和该子串的前半部分都是回文串,所 ...

  8. 杭电多校HDU 6599 I Love Palindrome String (回文树)题解

    题意: 定义一个串为\(super\)回文串为: \(\bullet\) 串s为主串str的一个子串,即\(s = str_lstr_{l + 1} \cdots str_r\) \(\bullet\ ...

  9. 【HDOJ6599】I Love Palindrome String(PAM,manacher)

    题意:给出一个由小写字母组成的长为n的字符串S,定义他的子串[L,R]为周驿东串当且仅当[L,R]为回文串且[L,(L+R)/2]为回文串 求i=[1,n] 所有长度为i的周驿东串的个数 n<= ...

随机推荐

  1. mongoose 开源http库

    Mongoose是一个用C编写的网络库.它为客户端和服务器模式实现TCP,UDP,HTTP,WebSocket,CoAP,MQTT的事件驱动的非阻塞API. 设计理念: Mongoose有三个基本的数 ...

  2. 区块链共识算法|RAFT和PBFT的区别

    这里有个很形象的比喻: 一个团队一定会有一个老大和普通成员.对于 raft 算法,共识过程就是:只要老大还没挂,老大说什么,我们(团队普通成员)就做什么,坚决执行.那什么时候重新老大呢?只有当老大挂了 ...

  3. JDK的二进制安装

    JDK的二进制安装步骤 1. Jdk1.8二进制包下载路径http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads- ...

  4. 在win32中使用SetWindowSubclass阻止Enter键

    使用阻止Enter键的编辑控件的简单子类来完成此操作: LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, L ...

  5. 安装虚拟环境 virtualenv

    前言 玩python 当然需要安装虚拟环境,这样就万一有多个项目,避免会冲突,如何安装 virtualenv: 下面如下: 输入 pip list cmd 你的电脑: 然后 输入 pip list: ...

  6. mybatis简单用法

    1.resultType 和 resultMap 引言: MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表 ...

  7. iOS自定义键盘的简单实现

    自定义键盘类VolumeInputKeyboardView: VolumeInputKeyboardView.h文件: #import <UIKit/UIKit.h> NS_ASSUME_ ...

  8. 16.合并两个排序的链表(python)

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. class Solution: # 返回合并后列表 def Merge(self, pHead1 ...

  9. 引用自定义的css或者js文件

    用script标签,src是js文件路径 <script type="text/javascript" src="./js/udc.js">< ...

  10. weblogic 10c and 12c 打补丁

    https://pan.baidu.com/s/17IaK1SYwHxwt-CRb0zDqXw