题目链接

题意:给定一个字符串\(|S|\le 3\times 10^5\)

对于每个 \(i\in [1,|S|]\) 求有多少子串\(s_ls_{l+1}\cdots s_r\)满足下面条件

  • \(r-l+1 = i\)
  • \(s_ls_{l+1}\cdots s_r\)是一个回文串
  • \(s_ls_{l+1}\cdots s_{\lfloor(l+r)/2\rfloor}\)也是一个回文串

回文树学习:https://blog.csdn.net/Clove_unique/article/details/53750322

根据条件可知\(s_ls_{l+1}\cdots s_{\lfloor(l+r)/2\rfloor-1} == s_{\lfloor(l+r)/2\rfloor}\cdots s_r\)

先用回文自动机求出本质不同的回文串

  • 第一种方法是回文树中创建新节点(意味着新的回文串)时判断该回文串是否满足上面条件,再建好树之后从后向前计算个数时累加即可
  • 第二种是利用回文树中fail指针特性,每次循环找fail所指的回文串是否满足条件,直到根节点或找到为止,此次寻找结果可以更新到下一层fail指针所指的节点中(避免多次重复寻找,不然会T)

第一种方法代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
typedef unsigned long long ull;
typedef long long ll;
ull has[N],pn[N],base = 131;
ull getVal(int l,int r){
return has[r] - has[l-1] * pn[r-l+1];
}
ll res[N];
char s[N];
namespace PAT{
const int SZ = 6e5+10;
int ch[SZ][26],fail[SZ],cnt[SZ],len[SZ],tot,last,pos[SZ],satisfy[SZ];
void init(int n){
for(int i=0;i<=n+10;i++){
fail[i] = cnt[i] = len[i] = 0;
for(int j=0;j<26;j++)ch[i][j] = 0;
}
s[0] = -1;fail[0] = 1;last = 0;
len[0] = 0;len[1] = -1,tot = 1;
}
inline int newnode(int x){
len[++tot] = x;return tot;
}
inline int getfail(int x,int n){
while(s[n-len[x]-1] != s[n])x = fail[x];
return x;
}
void create(char *s,int n){
s[0] = -1;
for(int i=1;i<=n;++i){
int t = s[i]- 'a';
int p = getfail(last,i);
if(!ch[p][t]){
int q = newnode(len[p]+2);
fail[q] = ch[getfail(fail[p],i)][t];
ch[p][t] = q;
int need = (len[q] + 1) /2;
if(len[q] == 1 || getVal(i-len[q]+1,i-len[q] + need) == getVal(i-need +1,i))satisfy[q] = 1;
else satisfy[q] = 0;
}
++cnt[last = ch[p][t]];
}
}
void solve(){
for(int i=tot;i>=2;i--){
cnt[fail[i]] += cnt[i];
if(satisfy[i])res[len[i]] += cnt[i];
}
}
}
int main(){
pn[0] = 1;
for(int i=1;i<N;i++)pn[i] = pn[i-1] * base; while(~scanf("%s",s+1)){
int n = strlen(s+1);
has[0] = 1;
for(int i=1;i<=n;i++){
has[i] = has[i-1] * base + s[i];
}
for(int i=1;i<=n;i++)res[i] = 0;
PAT::init(n);
PAT::create(s,n);
PAT::solve();
for(int i=1;i<n;i++)printf("%lld ",res[i]);
printf("%lld\n",res[n]);
}
return 0;
}

第二种方法code

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
typedef long long ll;
char s[N];
ll res[N];
namespace PAT{
const int SZ = 6e5+10;
int ch[SZ][26],fail[SZ],cnt[SZ],len[SZ],tot,last;
int be[SZ],ok[SZ];
void init(int n){
for(int i=0;i<=n+10;i++){
fail[i] = cnt[i] = len[i] = 0;
for(int j=0;j<26;j++)ch[i][j] = 0;
be[i] = ok[i] = 0;
}
s[0] = -1;fail[0] = 1;last = 0;
len[0] = 0;len[1] = -1;tot = 1;
}
inline int newnode(int x){
len[++tot] = x;return tot;
}
inline int getfail(int x,int n){
while(s[n-len[x]-1] != s[n])x = fail[x];
return x;
}
void create(char *s){
s[0] = -1;
for(int i=1;s[i];++i){
int t = s[i]- 'a';
int p = getfail(last,i);
if(!ch[p][t]){
int q = newnode(len[p]+2);
fail[q] = ch[getfail(fail[p],i)][t];
ch[p][t] = q;
}
++cnt[last = ch[p][t]];
}
}
void solve(){
for(int i=tot;i>=2;i--){
if(be[i] == 0)be[i] = i;
while(be[i] >= 2 && len[be[i]] > (len[i] + 1)/2)be[i] = fail[be[i]];
if(len[be[i]] == (len[i]+1)/2)ok[i] = 1;
be[fail[i]] = be[i];
}
for(int i=tot;i>=2;i--){
cnt[fail[i]] += cnt[i];
if(ok[i]) res[len[i]] += cnt[i];
}
}
}
int main(){
while(~scanf("%s",s+1)){
int n = strlen(s+1);
for(int i=1;i<=n;i++)res[i] = 0;
PAT::init(n);
PAT::create(s);
PAT::solve();
for(int i=1;i<n;i++)printf("%lld ",res[i]);
printf("%lld\n",res[n]);
}
return 0;
}

HDU-6599 I Love Palindrome String(回文自动机+字符串hash)的更多相关文章

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

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

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

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

  3. [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]也满足 ...

  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. CF932G Palindrome Partition(回文自动机)

    CF932G Palindrome Partition(回文自动机) Luogu 题解时间 首先将字符串 $ s[1...n] $ 变成 $ s[1]s[n]s[2]s[n-1]... $ 就变成了求 ...

  6. LeetCode Valid Palindrome 有效回文(字符串)

    class Solution { public: bool isPalindrome(string s) { if(s=="") return true; ) return tru ...

  7. 【CF932G】Palindrome Partition 回文自动机

    [CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_ ...

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

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

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

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

随机推荐

  1. Unity优化 1

    浅谈Unity中的GC以及优化(转) Unity 官方文档,正巧在博客园发现了已经有位大神(zblade)把原文翻译出来了,而且质量很高~,译文地址 在这里.下面我就可耻地把译文搬运了过来,作为上面思 ...

  2. wpf 中 Ellipse 对象对动画性能的影响

    vs2019 .NetFramework 4.8 win10-64 1909 接手一个wpf项目,某窗口中包含大量的 Shape 对象(线,矩形,圆形等). 这些内容要匀速的向左平移,类似于游戏&qu ...

  3. Session、Cookie与Token

    http协议是无状态协议 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到 ...

  4. Memcached Session Manager 共享tomcat session设置

    tomcat的lib下添加jar包 修改tomcat的conf目录下的context.xml文件 新增 sessionCookiePath="/" <Manager clas ...

  5. 【SpringBoot】Spring Boot,开发社区讨论交流网站首页。

    初识Spring Boot,开发社区讨论交流网站首页. 文章目录 初识Spring Boot,开发社区讨论交流网站首页. 1.项目简介 2. 搭建开发环境 JDK Apache Maven Intel ...

  6. MyBatis初级实战之三:springboot集成druid

    OpenWrite版: 欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kuber ...

  7. ctfshow—pwn10

    格式化字符串漏洞 具体什么是格式化字符串请大家参考如下文章 https://wiki.x10sec.org/pwn/fmtstr/fmtstr_intro/ printf函数格式化输出符号及详细说明 ...

  8. 攻防世界—pwn—level2

    题目分析 题目提示 下载文件后首先使用checksec检查文件保护机制 使用ida打开,查看伪代码 搜索字符串发现/bash/sh 信息收集 偏移量 system的地址 /bin/sh的地址 编写脚本 ...

  9. +load和+initialize方法调用时机

    一.+load方法什么时候调用 +load方法会在runtime加载类.分类时调用(程序运行起来会先去加载调用+load 跟你引用没有引用其头文件没有关系).每个类.分类的+load,在程序运行过程中 ...

  10. druid discard long time none received connection问题解析

    最新项目中用的druid连接数据库遇到一个困扰很久的问题 1 开始用的druid版本是1.1.22版本,由于业务需求,单个连接需要执行很久,理论上不需要用到自动回收,但为了安全,还是加了自动回收,时间 ...