题目链接: https://codeforces.com/contest/835/problem/D

注: 欢迎移步 https://codeforces.com/blog/entry/67839

题意: 一个回文串是\(1\)-回文的,如果一个回文串的左半部分和右半部分一样且都是\(k\)-回文串(右半部分是指长度为该串长度除以二下取整的后缀),则该串为\((k+1)\)回文串,满足该串是\(k\)回文串的最大\(k\)称作该串的回文级别。给定一个串\(s\), 对于每一个\(k=1,2,...,n\)求出该串中有多少个位置不同的\(k\)-回文串。\(n\le 5\times 10^6\). (除数据范围外与原题均相同)

题解: \(n^2\)的做法肯定是以子串为状态进行dp, 但是显然废状态太多了,只有回文串dp值非零,而一个串本质不同的回文串的个数是\(O(n)\)的。

所以,以本质不同的回文串作为状态进行dp. 本质不同的回文串一一对应回文自动机上的节点。设\(f[x]\)表示\(x\)节点代表回文串的回文级别。

然后转移方程显然: 若\(x\)不存在长度为\([\frac{x}{2}]\)(中括号表示下取整)的回文后缀,则\(dp[x]=1\), 否则\(dp[x]\)等于那个回文后缀的\(dp\)值+1.

dp完之后,我们求的是本质不同,但是题目要求求位置不同,所以还需要再统计一下每个点的子树大小。

时间复杂度\(O(n)\).

代码 (Codeforces 835D AC)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define llong long long
using namespace std; const int N = 1e6+2;
const int LGN = 23;
const int S = 26;
int son[N+3][S+1];
int fail[N+3];
int len[N+3];
int sz[N+3];
int tsz[N+3];
char a[N+3];
int dp[N+3];
int bd[N+3];
int ord[N+3];
int buc[N+3];
llong ans[N+3];
int n,siz,lstpos; void initPAM()
{
siz = lstpos = 1; fail[0] = fail[1] = 1; len[1] = -1; len[0] = 0; bd[0] = 0; bd[1] = 1;
} void insertchar(int id)
{
int p = lstpos;
while(a[id]!=a[id-len[p]-1]) {p = fail[p];}
if(!son[p][a[id]])
{
siz++; int u = siz,v = fail[p];
while(a[id]!=a[id-len[v]-1]) {v = fail[v];}
fail[u] = son[v][a[id]]; son[p][a[id]] = u; len[u] = len[p]+2;
if(len[u]<=2) {bd[u] = fail[u];}
else
{
bd[u] = bd[p];
while(a[id]!=a[id-len[bd[u]]-1] || (len[bd[u]]+2)*2>len[u])
{
bd[u] = fail[bd[u]];
}
bd[u] = son[bd[u]][a[id]];
}
if(len[bd[u]]==(len[u]>>1)) {dp[u] = max(0,dp[bd[u]])+1;}
else {dp[u] = 1;}
}
sz[son[p][a[id]]]++;
lstpos = son[p][a[id]];
} int main()
{
initPAM();
scanf("%s",a+1); n = strlen(a+1);
for(int i=1; i<=n; i++) a[i]-=96;
for(int i=1; i<=n; i++) {insertchar(i);}
for(int i=2; i<=siz; i++) {buc[len[i]]++;}
for(int i=1; i<=n; i++) {buc[i] += buc[i-1];}
for(int i=siz; i>=2; i--) {ord[(buc[len[i]]--)+1] = i;}
ord[0] = 1; ord[1] = 0;
for(int j=siz; j>=2; j--)
{
int u = ord[j];
sz[fail[u]] += sz[u];
}
for(int j=2; j<=siz; j++)
{
ans[dp[j]] += (llong)sz[j];
}
for(int j=LGN-1; j>=1; j--) ans[j] += ans[j+1];
for(int i=1; i<=n; i++) printf("%I64d\n",ans[i]);
return 0;
}

[加强版] Codeforces 835D Palindromic characteristics (回文自动机、DP)的更多相关文章

  1. 【XSY2534】【CF835D】Palindromic characteristics 回文自动机

    题目大意 ​ 一个字符串\(s\)是\(1\)−回文串当且仅当这个串是回文串. ​ 一个串\(s\)是\(k\)−回文串\((k>1)\)当且仅当\(s\)的前一半与后一半相同且\(s\)的前一 ...

  2. CodeForces 835D - Palindromic characteristics | Codeforces Round #427 (Div. 2)

    证明在Tutorial的评论版里 /* CodeForces 835D - Palindromic characteristics [ 分析,DP ] | Codeforces Round #427 ...

  3. Palindromic Tree 回文自动机-回文树 例题+讲解

    回文树,也叫回文自动机,是2014年被西伯利亚民族发明的,其功能如下: 1.求前缀字符串中的本质不同的回文串种类 2.求每个本质不同回文串的个数 3.以下标i为结尾的回文串个数/种类 4.每个本质不同 ...

  4. bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)

    bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...

  5. bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)

    bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp) bzoj Luogu 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符 ...

  6. 洛谷P4762 [CERC2014]Virus synthesis(回文自动机+dp)

    传送门 回文自动机的好题啊 先建一个回文自动机,然后记$dp[i]$表示转移到$i$节点代表的回文串的最少的需要次数 首先肯定2操作越多越好,经过2操作之后的串必定是一个回文串,所以最后的答案肯定是由 ...

  7. bzoj 4044: [Cerc2014] Virus synthesis【回文自动机+dp】

    建回文自动机,注意到一个回文串是可以通过一个长度小于等于这个串长度的一半的回文串添上一些字符然后复制得到的,也就是在自动机上向fa走,相当于treedp 每次都走显然会T,记录一个up,指向祖先中最下 ...

  8. [CERC2014]Virus synthesis【回文自动机+DP】

    [CERC2014]Virus synthesis 初始有一个空串,利用下面的操作构造给定串 SS . 1.串开头或末尾加一个字符 2.串开头或末尾加一个该串的逆串 求最小化操作数, \(|S| \l ...

  9. Codeforces 932G Palindrome Partition 回文树+DP

    题意:给定一个串,把串分为偶数段 假设分为$s_1,s_2,s_3....s_k$ 求满足$ s_1=s_k,s_2=s_{ k-1 }... $的方案数模$10^9+7$ $|S|\leq 10^6 ...

随机推荐

  1. Java代码规范_插件_阿里java开发手册

    给大家分享一个阿里巴巴的java开发规范,在日常自动化工作中我们可以参考一下,特别是用java进行coding的同学. 而且还可以利用相应的插件进行代码扫描检测,感兴趣的们可以马上应用到自动化中来. ...

  2. Android 触摸提示音【转】

    本文转载自:http://blog.csdn.net/Jin_HeZai/article/details/46791567 近期任务,涉及Android触摸提示音. 首先,定位源码目标.很显然的,在原 ...

  3. it人必进的几大网站

    1.chinaunix网址:http://www.chinaunix.net/简介:中国最大的linux/unix技术社区. 2.itpub网址:http://www.itpub.net/ 简介:有名 ...

  4. 如何解决error LNK2001(转载)

    转自:http://www.cnblogs.com/myzhijie/articles/1658545.html 解决外部符号错误:_main,_WinMain@16,__beginthreadex ...

  5. JSP所需要掌握的部分

    JSP基本语法 指令 <%@ 指令%> JSP指令是JSP的引擎 主要的两种指令是page和include(taglib) <%@ page import="java.ut ...

  6. go语言Notepad++简易开发环境搭建(windows)

    1.下载安装go语言:https://golang.org/dl/选择对应的平台,建议使用msi安装包,这个会帮你配置好环境变量(也许需要重启)对应的环境变量有: GOROOT - C:\Go\PAT ...

  7. SpringAop--系统日志简例

    通过Spring的Aop我们可以声明式的配置事务管理,那么同样可以通过SpringAop来进行处理的系统日志该如何实现呢? 一.数据表和实体类的准备 我们要管理系统日志,那么数据表和实体类是必不可少的 ...

  8. Kotlin实例----android5.0新特性之palette

    一.Palette的使用 使用Palette可以让我们从一张图片中拾取颜色,将拾取到的颜色赋予ActionBar,StatusBar以及UI背景色可以让界面色调实现统一或者加载不同图片时同步变化色调 ...

  9. SQL基本操作——ALTER

    ALTER TABLE 语句用于在已有的表中添加.修改或删除列. Persons 表: ID LastName FirstName Address City 1 Adams John Oxford S ...

  10. IE bug集锦

    ie8 iframe 不显示 问题描述: IE8的非兼容模式下(兼容模式是ie7,不存在),iframe会不显示: 可以通过Ctrl+A全选或者是调整窗口大小显示出来. 解决办法: 这是由于要显示的i ...