CF932G-Palindrome Partition【PAM】
正题
题目链接:https://www.luogu.com.cn/problem/CF932G
题目大意
给出一个长度为\(n\)的字符串,将其分为\(k\)段(\(k\)为任意偶数),记为\(p\)。要求满足对于任意\(i\)都有\(p_i=p_{k-i+1}\)。求方案数。
\(1\leq n\leq 10^6\)
解题思路
考虑将字符串化为\(S_1S_nS_2S_{n-1}S_3S_{n-2}...\)这样的形式,可以发现对于原本相同的段在这里就被表示为了一个偶回文子串。
那么问题就变为了划分若干个偶回文子串。设\(f_i\)表示前\(i\)个的方案的话有一种比较简单的做法,建立\(PAM\)后求出每个前缀的所有偶回文后缀,然后暴力转移。
但是这样的是\(O(n^2)\)的,时间复杂度不符合要求,考虑优化。对于一个回文串来说它的所有回文后缀就是它的\(border\)。而\(broder\)有一个性质就是所有\(broder\)的长度可以被划分成\(log\)个等差数列。
我们可以在\(PAM\)上维护这些等差数列,记录\(top_i\)表示节点\(i\)所在的等差数列的顶部,然后每次使用\(top\)往上跳。加入新的\(x\)节点(或者覆盖以前的已经有的节点)的时候累计一下自己作为末尾时所在等差数列方案和就好了
时间复杂度\(O(n\log n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+10,P=1e9+7;
int n,cnt,pos[N],len[N],dis[N],fa[N],top[N],ch[N][26];
char t[N],s[N];int f[N],g[N];
int jump(int x,int p){
while(s[p-len[x]-1]!=s[p])x=fa[x];
return x;
}
int Insert(int x,int p){
x=jump(x,p);
int c=s[p]-'a';
if(!ch[x][c]){
++cnt;len[cnt]=len[x]+2;
int y=jump(fa[x],p);
fa[cnt]=ch[y][c];y=cnt;
dis[y]=len[y]-len[fa[y]];
if(dis[y]!=dis[fa[y]])top[y]=y;
else top[y]=top[fa[y]];ch[x][c]=y;
}
return ch[x][c];
}
int main()
{
scanf("%s",t+1);n=strlen(t+1);
if(n&1)return puts("0")&0;
for(int i=1;i<=n;i+=2)s[i]=t[i/2+1];
for(int i=2;i<=n;i+=2)s[i]=t[n-i/2+1];
len[1]=-1;fa[0]=top[1]=cnt=1;
for(int i=1;i<=n;i++)
pos[i]=Insert(pos[i-1],i);
f[0]=1;
for(int i=1;i<=n;i++){
for(int x=pos[i];x;x=fa[top[x]]){
g[x]=f[i-len[top[x]]];
if(x!=top[x])(g[x]+=g[fa[x]])%=P;
if(!(i&1))(f[i]+=g[x])%=P;
}
}
printf("%d\n",f[n]);
return 0;
}
CF932G-Palindrome Partition【PAM】的更多相关文章
- CF932G Palindrome Partition(回文自动机)
CF932G Palindrome Partition(回文自动机) Luogu 题解时间 首先将字符串 $ s[1...n] $ 变成 $ s[1]s[n]s[2]s[n-1]... $ 就变成了求 ...
- 680. Valid Palindrome II【easy】
680. Valid Palindrome II[easy] Given a non-empty string s, you may delete at most one character. Jud ...
- Device "/dev/sdg" is not a partition【再续】
之前创建asm磁盘的时候总结过一下错误:http://blog.csdn.net/rhys_oracle/article/details/17029333 当今天情况是这种.例如以下: 在使用open ...
- Uva - 12050 Palindrome Numbers【数论】
题目链接:uva 12050 - Palindrome Numbers 题意:求第n个回文串 思路:首先可以知道的是长度为k的回文串个数有9*10^(k-1),那么依次计算,得出n是长度为多少的串,然 ...
- CF932G Palindrome Partition
思路 首先把字符串变为\(S[1]S[n]s[2]s[n-1] \dots\) 这样原来的一个合法的划分方案就变成了用k个长度为偶数的回文子串划分的方案, 然后直接DP,对i位置,可转移的位置就是它的 ...
- HDU 2018 Multi-University Training Contest 1 Triangle Partition 【YY】
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6300 Triangle Partition Time Limit: 2000/1000 MS (Java ...
- 680. Valid Palindrome II【Easy】【双指针-可以删除一个字符,判断是否能构成回文字符串】
Given a non-empty string s, you may delete at most one character. Judge whether you can make it a pa ...
- 491. Palindrome Number【easy】
Check a positive number is a palindrome or not. A palindrome number is that if you reverse the whole ...
- 洛谷P5496 回文自动机【PAM】模板
回文自动机模板 1.一个串的本质不同的回文串数量是\(O(n)\)级别的 2.回文自动机的状态数不超过串长,且状态数等于本质不同的回文串数量,除了奇偶两个根节点 3.如何统计所有回文串的数量,类似后缀 ...
随机推荐
- java批量下载文件为zip包
批量下载文件为zip包的工具类 package com.meeno.trainsys.util; import javax.servlet.http.HttpServletRequest; impor ...
- 【协议】AAA Radius协议的常用报文分析
写在前面的话 RADIUS:Remote Authentication Dial In User Service,远程用户拨号认证系统由RFC2865,RFC2866定义,是应用最广泛的AAA协议. ...
- HttpClient 4.3教程-前言
前言 Http协议应该是互联网中最重要的协议.持续增长的web服务.可联网的家用电器等都在继承并拓展着Http协议,向着浏览器之外的方向发展. 虽然jdk中的java.net包中提供了一些基本的方法, ...
- 【转】SpringCloud学习
Spring Cloud Alibaba与Spring Boot.Spring Cloud之间不得不说的版本关系 这篇博文是临时增加出来的内容,主要是由于最近连载<Spring Cloud ...
- idea项目在maven projects中显示灰色的解决办法。建新建module src变成标准的文件夹
在使用idea的过程中,有时会遇到其中一个maven模块变成灰色(可以通过view - tool windows -> maven projects 现实),如下所示: 造成这个的原因可能是忽略 ...
- 关于Typora的使用
关于Typora的使用 今天介绍一个做笔记用的一款markdown编辑器,用了之后,顺利被圈粉: Typora,美观小众,可用性强! 和传统的markdown编辑器不一样,传统的markdown编辑器 ...
- ES6扩展——数组的新方法(Array.from、Array.of、Array.fill、Array.includes、keys values entries 、find)
1.Array.from(objec,回调函数)将一个ArrayLike对象或者Iterable对象(类数组对象)转换成一个数组 1)该类数组对象必须具有length属性,用于指定数组的长度.如果没有 ...
- ☕【Java技术指南】「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!
前提介绍 本章主要介绍相关线程声明周期的转换机制以及声明周期的流转关系以及相关AQS的实现和相关的基本原理,配合这相关官方文档的中英文互译的介绍. 线程状态流转及生命周期 当线程被创建并启动以后,它既 ...
- Linux下查看哪个网口插了网线
场景: 一台服务器有多个网卡,一个网卡有多个网口,当插了一根网线的时候,不知道网线是插在哪一个网口. 1.查看网口信息 2.查看网口是否插了网线(命令ethtool) 命令:ethtool + 网口名 ...
- Node.js躬行记(9)——微前端实践
后台管理系统使用的是umi框架,随着公司业务的发展,目前已经变成了一个巨石应用,越来越难维护,有必要对其进行拆分了. 计划是从市面上挑选一个成熟的微前端框架,首先选择的是 icestark,虽然文档中 ...