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\)满足下面条件 \( ...
随机推荐
- Solution -「Gym 102956F」Find the XOR
\(\mathcal{Description}\) Link. 给定 \(n\) 个点 \(m\) 条边的连通无向图 \(G\),边有边权.其中 \(u,v\) 的距离 \(d(u,v)\) ...
- MyBatis功能点二应用:第三方分页插件使用
pageHelper分⻚插件使用 在前面文章MyBatis功能点二:plugins插件使用 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了自定义插件的使用,本文介绍第三方插件pa ...
- 6.Flink实时项目之业务数据分流
在上一篇文章中,我们已经获取到了业务数据的输出流,分别是dim层维度数据的输出流,及dwd层事实数据的输出流,接下来我们要做的就是把这些输出流分别再流向对应的数据介质中,dim层流向hbase中,dw ...
- nginx加大缓存
http { server { listen 0.0.0.0:81; server_name localhost; -- proxy_buffer_size 128k; proxy_buffers 3 ...
- Python中from … import …语句
from - import -语句可以让你从模块中导入一个指定的部分到当前模块
- C#内联函数 特性 MethodImplOptions.AggressiveInlining)
[MethodImpl(MethodImplOptions.AggressiveInlining)] 内联函数 Impl:implement的缩写 内联函数 在计算机科学中,内联函数(有时称作在线函数 ...
- 【C++ 调试】增量链接 Incremental Linking
概述: Incremental Linking翻译成中文就是"增量链接",是一个链接的参数选项,作用就是为了提高链接速度的.什么意思呢?不选用增量链接时,每次修改或新增代码后进行链 ...
- c# $ @特殊字符
c# @ 停止字符串中的转义字符,让字符串内的转义字符当正常字符输入. 因此,如果你需要类似"所见所得"效果的赋值,逐字字符串赋值方式会是你的首选!此外,需要注意的是,当使用符号 ...
- 哈工大 信息安全实验 XSS跨站脚本攻击原理与实践
XX大学XX学院 <网络攻击与防御> 实验报告 实验报告撰写要求 实验操作是教学过程中理论联系实际的重要环节,而实验报告的撰写又是知识系统化的吸收和升华过程,因此,实验报告应该体现完整性. ...
- omnet++:cMessage、cSimpleModule、cGate
cMessage Message可以被调度(self-message).取消.从一个Gate发送出去.直接发给另一个module:所有以上,都是通过cSimpleModule来实现的. Message ...