正题

题目链接: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】的更多相关文章

  1. CF932G Palindrome Partition(回文自动机)

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

  2. 680. Valid Palindrome II【easy】

    680. Valid Palindrome II[easy] Given a non-empty string s, you may delete at most one character. Jud ...

  3. Device &quot;/dev/sdg&quot; is not a partition【再续】

    之前创建asm磁盘的时候总结过一下错误:http://blog.csdn.net/rhys_oracle/article/details/17029333 当今天情况是这种.例如以下: 在使用open ...

  4. Uva - 12050 Palindrome Numbers【数论】

    题目链接:uva 12050 - Palindrome Numbers 题意:求第n个回文串 思路:首先可以知道的是长度为k的回文串个数有9*10^(k-1),那么依次计算,得出n是长度为多少的串,然 ...

  5. CF932G Palindrome Partition

    思路 首先把字符串变为\(S[1]S[n]s[2]s[n-1] \dots\) 这样原来的一个合法的划分方案就变成了用k个长度为偶数的回文子串划分的方案, 然后直接DP,对i位置,可转移的位置就是它的 ...

  6. 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 ...

  7. 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 ...

  8. 491. Palindrome Number【easy】

    Check a positive number is a palindrome or not. A palindrome number is that if you reverse the whole ...

  9. 洛谷P5496 回文自动机【PAM】模板

    回文自动机模板 1.一个串的本质不同的回文串数量是\(O(n)\)级别的 2.回文自动机的状态数不超过串长,且状态数等于本质不同的回文串数量,除了奇偶两个根节点 3.如何统计所有回文串的数量,类似后缀 ...

随机推荐

  1. C++ Opencv图像直方图

    Mat image = imread("D:/ju.jpg"); imshow("素材图", image); int bins = 256; //直条为256 ...

  2. 【java虚拟机】内存分配与回收策略

    作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6557473.html 前言 对象的内存分配,往大的方向上讲,就是在堆上分配,少数情况下也可能会直接分配在老 ...

  3. Commons-Collections(二)之map

    BidiMap: 双重Map 使用双向映射,可以使用值查找键,并且可以使用键轻松查找值.(自然,它可以根绝key移除,也可以根据value移除) public interface BidiMap< ...

  4. 连接共享打印机失败错误代码0x80070035

    局域网内共享打印机非常方便,但是在连接中经常遇到问题,其中出现错误代码0x80070035的概率非常之高! 1.必须确保有关打印功能的相关服务都处于自动启动状态,重点检查TCP/IP NetBIOS ...

  5. Java抽象类(abstract)

    抽象类和接口 一.抽象类 1.什么是抽象类? 类和类之间具有共同的特征,将这些特征提取出来,形成的就是抽象类. 类到对象是实例化,对象到类是抽象. 抽象类和具体类是相对的概念."抽象&quo ...

  6. 痞子衡嵌入式:简析i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道. ECC 是 "Error Correc ...

  7. 浅谈C#更改令牌ChangeToken

    前言 在上篇文章浅谈C#取消令牌CancellationTokenSource一文中我们讲解了CancellationTokenSource,它的主要功能就是分发一个令牌,当我取消令牌我可以进行一些回 ...

  8. MMM双主-双从读写分离部署

    原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 前期规划 1.1 主机规划 1.2 虚拟IP规划 1.3 用户列表 1.4 整 ...

  9. 在python3.6环境下使用cxfreeze打包程序

    在python3.6环境下使用cxfreeze打包程序 环境:python3.6 打包程序:aliens_invasion 原本想使用pyintaller 进行打包,使用pip的安装过程也没有问题,打 ...

  10. GIMP 一键均匀添加多条参考线 一键均匀切分图片

    添加参考线 #!/usr/bin/env python2 # -*- coding: utf-8 -*- from gimpfu import * # orientation: ORIENTATION ...