题目链接: 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. YTU 2774: Prepare for CET6

    2774: Prepare for CET6 时间限制: 1 Sec  内存限制: 128 MB 提交: 40  解决: 37 题目描述 Hard to force the CET4&6 is ...

  2. Bing Maps进阶系列一:初识Bing Maps地图服务

    Bing Maps进阶系列一:初识Bing Maps地图服务 Bing Maps提供了一组WCF的地图服务,使用这些服务我们可以方便的在自己的应用系统里实现地理位置搜索等相关功能.他们分别是地理编码服 ...

  3. yum -y --downloadonly --downloaddir=/ruiy upggrde;

    事务概要================================================================================================ ...

  4. Grunt环境搭建及使用

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过 ...

  5. 数据库异常 :java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

    最近在新项目中突然出现了  java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES) ...

  6. C#窗体间传值的简便方法/工具

    一.问题:窗体间传值必须需要窗体之间有联系,具体有如下方式 窗体间传值涉及到窗体A必须拥有窗体B,这样才可以实现A-B之间传值 窗体A与窗体B在窗体/实例C中,A-B可互相通讯 其他方式,不细讨论,复 ...

  7. css样式之vertical-align垂直居中的应用

    css样式之vertical-align垂直居中的应用:将图片垂直左右居中 元素垂直居中 1:必须给容器父元素加上text-align:center 2:必须给当前元素转换成行内块元素,display ...

  8. js模拟复制

    现在浏览器种类也越来越多,诸如 IE.Firefox.Chrome.Safari等等,因此现在要实现一个js复制内容到剪贴板的小功能就不是一件那么容易的事了.   一.实现点击按钮,复制文本框中的的内 ...

  9. Gym - 100920E 2010-2011 OpenCup IX Onsite, II Yandex Summer School E.Paint 状压DP

    题面 题意:给你n(20)个点,m(40条边),让你给每条边染一种颜色,白色0元,红色2元,蓝色1元,现在要保证每一条白边相邻的有一条红边,问至少花多少 题解:刚开始想的时候,好像觉得只用染红色和白色 ...

  10. selenium3 + python - autoit上传文件

    一.环境准备: 1.可以autoit官网上下载,安装 http://www.autoitscript.com/site/ 2.AutoIt里面几个菜单功能介绍: SciTE Script Editor ...