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 题解: ...
随机推荐
- spark-sql缩减版样例:获取每日top3搜索词和各自的次数,包括总次数
//获取出每天前3的搜索词 ArrayList<String> log = new ArrayList<String>(); log.add("2015-10-01, ...
- mock server 实现get方法的接口(二)
mock server 实现get方法的接口(二) 下面是实现查询品牌的接口demo: 1.当response数据量小的时候,可以直接使用json, mock会自动设置headers为applicat ...
- php 数据库乱码。。。php 移动临时文件
数据库乱码,三个位置 处理好不会乱码 第一前台,传到后台: 第二后台,传到数据库: 第三数据库,存入数据库: 详解 https://www.cnblogs.com/zhoujinyi/p/46188 ...
- vue 子组件调用父组件的方法
vue中 父子组件的通信: 子组件通过 props: { //子组件中写的. childMsg: { //字段名 type: Array,//类型 default: [0,0,0] //这样可以指定默 ...
- js动态改变setInterval的时间
<!DOCTYPE html> <html> <head> <!--meta name="viewport" content=" ...
- 时序图中的生命线与类绑定(EA)
使用时序图时序图( Sequence Diagram)时,有时候在起初拖放放的对象生命线未绑定相关的类. 如果: 但在后期需要和类进行绑定. 那么需要如下设置,右键你要关联的对象生命线,选择Advan ...
- Java 基础 多线程进阶(锁,线程安全)
一,前言 前面我们已经对线程和线程池有一定的了解,但是只要说到多线程,肯定需要考虑线程安全等问题.接下来我们就来好好聊聊这些问题. 二,线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段 ...
- 【菜鸟学Python】案例一:汇率换算
汇率换算V1.0 案例描述: 设计一个汇率换算器程序,其功能是将外币换算成人民币,或者相反 案例分析: 分析问题:分析问题的计算部分: 确定问题:将问题划分为输入.处理及输出部分: 设计算法:计算部分 ...
- springboot自动生成mysql的DAO层代码
springboot提供了强大丰富的整合内容,但是每次要写一堆dao层的xml或者数据库相关的配置代码的时候,还是挺繁琐又容易出错的. 可以用mybatis-generator自动生成代码: 只需要加 ...
- Apache Kylin学习资料
官方文档: http://kylin.apache.org/cn/docs/tutorial/web.html kylin对接hive实现实时查询:https://www.cnblogs.com/65 ...