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

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

#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. js 学习一 猜数字游戏

    知识点 js 操作元素 增 (document.createElement(),document.body.appendChild()), 删(parentNode.removeChild()) ,改 ...

  2. python多线程之threading、ThreadPoolExecutor.map

    背景: 某个应用场景需要从数据库中取出几十万的数据时,需要对每个数据进行相应的操作.逐个数据处理过慢,于是考虑对数据进行分段线程处理: 方法一:使用threading模块 代码: # -*- codi ...

  3. linux格式化磁盘命令

    linux格式化磁盘命令           linux mkfs         指令:mkfs 使用权限 : 超级使用者 使用方式 : mkfs [-V] [-t fstype] [fs-opti ...

  4. JS基础知识二

    JS控制语句 switch 语句用于基于不同的条件来执行不同的动作 <script> function myFunction(){ var x; var d=new Date().getD ...

  5. 在Scrapy里设置Cookies 要注意一点!

    1.requests里设置cookies,可以将cookies放入headers里一同提交. {'Accept': 'text/html,application/xhtml+xml,applicati ...

  6. rsyncd.conf配置文件

    rsyncd.conf配置文件     #Rsync server#created by oldboy 15:01 2009-6-5##rsyncd.conf start##uid = rootgid ...

  7. CodeForces-449B(单源最短路,思维)

    链接: https://vjudge.net/problem/CodeForces-449B 题意: Jzzhu is the president of country A. There are n ...

  8. 【NOIP2014模拟10.25A组】画矩形

    题目 分析 由于要求按时间顺序来操作,考虑整体二分: 对于一段二分出来的区间,将左区间的修改和右区间的查询取出来,每次更新每个查询的答案,正确性显然. 现在有一对修改和查询的操作(保证所有的查询都在修 ...

  9. 17.树的子结构(python)

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) class Solution: def HasSubtree(self, pRoot1, pRoo ...

  10. 19. ClustrixDB 执行计划解读

    EXPLAIN语句用于显示ClustrixDB查询优化器(也称为Sierra)如何执行INSERT.SELECT.UPDATE和DELETE语句.EXPLAIN的输出有三列: Operation - ...