CF932G Palindrome Partition(回文自动机)
CF932G Palindrome Partition(回文自动机)
题解时间
首先将字符串 $ s[1...n] $ 变成 $ s[1]s[n]s[2]s[n-1]... $
就变成了求将字符串全部划分为偶回文串的方案数。
建回文树大力跳$ fail $ 直接 $ dp $ 的复杂度是十分优秀的 $ O ( n ^ {2} ) $。
优化不容易想到。
考虑字符串上第 $ j $ 位为结尾的所有回文子串,毫无疑问它们在树上是一条链。
但它有个更重要的性质。
其中所有长度 $ > j / 2 $ 的子串的 $ len $ 等差。
证明有点难,但这个结论可能对做过[WC2016]论战捆竹竿的人来说十分熟悉。
然后将等差段的dp值整合到一起,每次跳就是 $ O( log_{2} n ) $。
然后就可以做了。
#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
struct pat{int x,y;pat(int x=0,int y=0):x(x),y(y){}bool operator<(const pat &p)const{return x==p.x?y<p.y:x<p.x;}};
template<typename TP>inline void read(TP &tar)
{
TP ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
tar=ret*f;
}
namespace RKK
{
const int N=1000011,mo=1000000007;
void doadd(int &a,int b){if((a+=b)>=mo) a-=mo;}
int dlen[N],anc[N];
struct remilia{int tranc[26],len,fail;};
struct sakuya
{
remilia p[N];
int tcnt,fin;
void init()
{
tcnt=fin=1;
p[0].len=0,p[1].len=-1;
p[0].fail=p[1].fail=1;
anc[0]=1;
}
sakuya(){init();}
int match(char *s,int i,int px){return s[i-p[px].len-1]==s[i];}
void ins(char *s,int i)
{
int ch=s[i]-'a';
int npx,lpx,lpy;
lpx=fin;
while(!match(s,i,lpx)) lpx=p[lpx].fail;
if(!p[lpx].tranc[ch])
{
npx=++tcnt,p[npx].len=p[lpx].len+2;
lpy=p[lpx].fail;
while(!match(s,i,lpy)) lpy=p[lpy].fail;
p[npx].fail=p[lpy].tranc[ch];
p[lpx].tranc[ch]=npx;
dlen[npx]=p[npx].len-p[p[npx].fail].len;
anc[npx]=p[npx].fail;if(dlen[npx]==dlen[p[npx].fail]) anc[npx]=anc[p[npx].fail];
}
fin=p[lpx].tranc[ch];
}
}pam;
int n;char str[N],rts[N];
int dp[N],dg[N];
int main()
{
#ifdef RDEBUG
freopen("sample.in","r",stdin);
#endif
scanf("%s",str+1),n=strlen(str+1);
for(int i=1;i<=n>>1;i++) rts[(i<<1)-1]=str[i];
reverse(str+1,str+1+n);
for(int i=1;i<=n>>1;i++) rts[i<<1]=str[i];
dg[0]=1;
for(int i=1;i<=n;i++)
{
pam.ins(rts,i);for(int px=pam.fin;px;px=anc[px])
{
dp[px]=dg[i-pam.p[anc[px]].len-dlen[px]];
if(anc[px]!=pam.p[px].fail) doadd(dp[px],dp[pam.p[px].fail]);
if((i&1)==0) doadd(dg[i],dp[px]);
}
}
printf("%d\n",dg[n]);
return 0;
}
}
int main(){return RKK::main();}
CF932G Palindrome Partition(回文自动机)的更多相关文章
- 【CF932G】Palindrome Partition 回文自动机
[CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_ ...
- [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]也满足 ...
- 2019牛客暑期多校训练营(第六场)C - Palindrome Mouse (回文自动机)
https://ac.nowcoder.com/acm/contest/886/C 题意: 给出一个串A , 集合S里面为A串的回文字串 , 现在在集合S里面找出多少对(a,b),b为a的字串 分析: ...
- hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash
题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...
- Codeforces 932G Palindrome Partition - 回文树 - 动态规划
题目传送门 通往???的传送点 通往神秘地带的传送点 通往未知地带的传送点 题目大意 给定一个串$s$,要求将$s$划分为$t_{1}t_{2}\cdots t_{k}$,其中$2\mid k$,且$ ...
- 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 ...
- 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 ...
- WHU 583 Palindrome ( 回文自动机 && 本质不同的回文串的个数 )
题目链接 题意 : 给你一个串.要你将其划分成两个串.使得左边的串的本质不同回文子串的个数是右边串的两倍.对于每一个这样子的划分.其对答案的贡献就是左边串的长度.现在要你找出所有这样子的划分.并将贡献 ...
- HDU-6599 I Love Palindrome String(回文自动机+字符串hash)
题目链接 题意:给定一个字符串\(|S|\le 3\times 10^5\) 对于每个 \(i\in [1,|S|]\) 求有多少子串\(s_ls_{l+1}\cdots s_r\)满足下面条件 \( ...
随机推荐
- Linux常用命令在Ubuntu 16下(个人笔记)
可以通过 tab键来补全提示命令或者目录,终端命令的格式: 命令 [-选项,多个选项可以结合写] [参数] , 大多数情况可以通过 ctrl c 退出命令 磁盘管理 pwd 查看当前所在目录 即:pr ...
- Go Exec 僵尸与孤儿进程
原文地址:Go Exec 僵尸与孤儿进程 最近,使用 golang 去管理本地应用的生命周期,期间有几个有趣的点,今天就一起看下. 场景一 我们来看看下面两个脚本会产生什么问题: 创建两个 shell ...
- 用图帮你了解https的原理
Http存在的问题 上过网的朋友都知道,网络是非常不安全的.尤其是公共场所很多免费的wifi,或许只是攻击者的一个诱饵.还有大家平时喜欢用的万能钥匙,等等.那我们平时上网可能会存在哪些风险呢? 泄密, ...
- 【C#基础知识】C#控制台程序入口函数 Main(string[] args) 参数详解
测试环境vs2019+.net5.0 请看 :https://cloud.tencent.com/developer/article/1507934 本测试环境vs2022+.net6.0 +wind ...
- spring的依赖注入的四种方式,数组与集合注入;引用注入;内部bean注入
三种注入方式 第一种: 基于构造函数 hi.java (bean) package test_one; public class hi { private String name; public hi ...
- random_sample() takes at most 1 positional argument (2 given)
是random模块下的sample函数,而不是np.random.
- 革命性创新,动画杀手锏 @scroll-timeline
在 CSS 规范 Scroll-linked Animations 中,推出了一个划时代的 CSS 功能.也就是 -- The @scroll-timeline at-rule,直译过来就是滚动时间线 ...
- JAVA Object类方法
目录 Object类详解 一.==和equals的对比 1.1 ==是一个比较运算符 1.2 equals方法 二.hashCode方法 三.toString方法 四.finalize方法 Objec ...
- ASP.NET Core 简单集成签发 JWT (JSON Web Tokens)
什么是 JWT ? 从 https://jwt.io/ 可以了解到对 JWT 的描述:JSON Web Tokens are an open, industry standard RFC 7519 m ...
- Lua中如何实现类似gdb的断点调试--05优化断点信息数据结构
在上一篇04优化钩子事件处理中,我们在钩子函数中引入了call和return事件的处理,对性能进行了优化. 细心的同学可能已经发现了,我们的hook函数中call事件和line都需要对整个断点表进行遍 ...