CF932G Palindrome Partition
思路
首先把字符串变为\(S[1]S[n]s[2]s[n-1] \dots\)
这样原来的一个合法的划分方案就变成了用k个长度为偶数的回文子串划分的方案,
然后直接DP,对i位置,可转移的位置就是它的几个回文后缀,在PAM上跳fail即可
但是复杂度是假的,一旦串的每个字符都相同,就需要跳\(O(n)\)次fail,总复杂度变成了\(O(n^2)\)
所以有这样一个性质,对一个节点x,它的所有fail的len最多是log个等差数列,因为对于长度大于\(\frac{len}{2}\)的情况,由于回文树的性质,长度一定是一个等差数列,每次len/2,所以有log段
考虑直接对这log端的贡献转移,在当前的位置i,设之前三个位置为a1,a2,a3(a1>a2>a3),由于回文串的性质S[i-a1,i-d]=S[i-a2,i],S[i-a2,i-d]=S[i-a3,i],所以a2,a3在i-d处已经被统计过了,加上i-a1的贡献即可
复杂度\(O(n\log n)\)
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MOD = 1e9+7;
int trans[1000100][26],fail[1000100],Nodecnt,len[1000100],last,n,dp[1000100],pre[1000100],f[1000100],inc[1000100];
char mids[1000100],s[1000100];
int New_state(int _len){
len[Nodecnt]=_len;
return Nodecnt++;
}
int get_fail(int p,int n){
while(mids[n-len[p]-1]!=mids[n])
p=fail[p];
return p;
}
void insert(int n){
int cur=get_fail(last,n);
if(!trans[cur][mids[n]]){
int t=New_state(len[cur]+2);
fail[t]=trans[get_fail(fail[cur],n)][mids[n]];
trans[cur][mids[n]]=t;
inc[t]=len[t]-len[fail[t]];
if(inc[t]==inc[fail[t]])
pre[t]=pre[fail[t]];
else
pre[t]=fail[t];
}
last=trans[cur][mids[n]];
}
int main(){
mids[0]=-1;
New_state(0);
fail[0]=1;
New_state(-1);
last=0;
scanf("%s",s+1);
n=strlen(s+1);
// printf("n=%d\n",n);
dp[0]=1;
int inq=0;
for(int i=1;i<=n/2;i++){
mids[++inq]=s[i]-'a';
insert(inq);
for(int j=last;j;j=pre[j]){
f[j]=dp[inq-len[pre[j]]-inc[j]];
if(pre[j]!=fail[j])
f[j]=(f[j]+f[fail[j]])%MOD;
if(!(inq&1))
dp[inq]=(dp[inq]+f[j])%MOD;
}
mids[++inq]=s[n-i+1]-'a';
insert(inq);
for(int j=last;j;j=pre[j]){
f[j]=dp[inq-len[pre[j]]-inc[j]];
if(pre[j]!=fail[j])
f[j]=(f[j]+f[fail[j]])%MOD;
if(!(inq&1))
dp[inq]=(dp[inq]+f[j])%MOD;
}
}
// for(int i=1;i<=n;i++)
// putchar(mids[i]+'a');
// putchar('\n');
printf("%d\n",dp[n]);
return 0;
}
CF932G Palindrome Partition的更多相关文章
- CF932G Palindrome Partition(回文自动机)
CF932G Palindrome Partition(回文自动机) Luogu 题解时间 首先将字符串 $ s[1...n] $ 变成 $ s[1]s[n]s[2]s[n-1]... $ 就变成了求 ...
- 【CF932G】Palindrome Partition(回文树,动态规划)
[CF932G]Palindrome Partition(回文树,动态规划) 题面 CF 翻译: 给定一个串,把串分为偶数段 假设分为了\(s1,s2,s3....sk\) 求,满足\(s_1=s_k ...
- 【CF932G】Palindrome Partition 回文自动机
[CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_ ...
- LeetCode: Palindrome Partition
LeetCode: Palindrome Partition Given a string s, partition s such that every substring of the partit ...
- Leetcode: Palindrome Partition I II
题目一, 题目二 思路 1. 第一遍做时就参考别人的, 现在又忘记了 做的时候使用的是二维动态规划, 超时加超内存 2. 只当 string 左部分是回文的时候才有可能减少 cut 3. 一维动规. ...
- [Leetcode] palindrome partition ii 回文分区
Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...
- 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 ...
- Palindrome Partition CodeForces - 932G 回文树+DP+(回文后缀的等差性质)
题意: 给出一个长度为偶数的字符串S,要求把S分成k部分,其中k为任意偶数,设为a[1..k],且满足对于任意的i,有a[i]=a[k-i+1].问划分的方案数. n<=1000000 题解: ...
随机推荐
- Jmeter压测基础(二)——Badboy功能、Jmeter参数化、检查点、集合点、动态关联、图形监控
Badboy 以下稍微介绍一下badboy的部分功能: 1.Record;play(badboy打开后默认是recording状态) 2.Assertion(检查点/断言) 3.Variable: t ...
- 精心调制的Bash主题分享
第一个是米色背景, 一样遵守蓝色为目录的习惯, 字体为浅灰色,代码和终端看起来相对比较清晰 第二个则是 深海蓝的背景风格,字体都选择饱和度较高的颜色,如下图 终端 配置方法,这里以 mintty 也就 ...
- python GUI图形化编程-----wxpython
一.python gui(图形化)模块介绍: Tkinter :是python最简单的图形化模块,总共只有14种组建 Pyqt :是python最复杂也是使用最广泛的图形化 Wx ...
- 普通Java Web项目为什么lib包要放在WEB-INF下
首先一个项目要编译好之后才能部署到Tomcat中运行. Tomcat运行时如何找编译好的.class文件呢,其实Tomcat下的web项目有两个预置的classpath(就是能找到.class文件的入 ...
- windows red5相关
red5部署 前段时间把red5服务器搭建好了,现在记录下是如何搭建的.1,下载对应版本的red5https://github.com/Red5/red5-server/releases2,如果没有安 ...
- 013-mac重做系统后的软件安装
一.系统设置 1.屏幕设置:系统偏好设置→显示器→排列,多个显示器可以排列组合 2.touch bar功能键设置:系统偏好设置→键盘→键盘,触控栏设置 F1 3.程序坞[dock]设置:系统偏好设置→ ...
- IP地址子网划分
广播数据包: 要弄清为何需要划分子网,就需要了解网络传输过程中的广播概念. 经过多年的发展,交换机基本替代集线器,成为网络中主要的端终接入网络的基础设备,这也使得广播包发送数量有明显的减少,但交换机一 ...
- 3.1.3 Spring之AOP
三.Spring之AOP 1. 代理模式 (1) 什么是代理模式? 代理模式是面向对象编程的23种基础设计模式之一.为其他对象(代理对象)提供一种代理以控制对这个对象(源对象)的访问. 就是说,声明一 ...
- C++模板的要点
1.函数模板与普通函数的区别: 普通函数可以进行自动类型转化,而函数模板不可以. 举个例子 //函数模板 template<class T> void show(T a,T b){ cou ...
- mysql----------原生的sql里面如何根据case then排序
1.按照三个字段都符合条件来排序 ORDER BY ( CASE WHEN is_top = 1 AND top_end_time>UNIX_TIMESTAMP() AN ...