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]];elsepre[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;
}
转载于:https://www.cnblogs.com/dreagonm/p/10748119.html
CF932G Palindrome Partition相关推荐
- Leetcode: Palindrome Partition I II
题目一, 题目二 思路 1. 第一遍做时就参考别人的, 现在又忘记了 做的时候使用的是二维动态规划, 超时加超内存 2. 只当 string 左部分是回文的时候才有可能减少 cut 3. 一维动规. ...
- CodeForces - 932G Palindrome Partition(回文自动机+Palindrome Series优化dp)
题目链接:点击查看 题目大意:给出一个长度为偶数的字符串,问将其分割成 k 个子串记为 a[ 1 ] , a[ 2 ] ... a[ k ] ,且满足 a[ i ] == a[ k - i + 1 ] ...
- Contest Record
Contest 1135 at HZOI Problem A: 优美的棋 发现一个可以证明的规律就是了-- 忘记给<<运算的左边变量转化为long long类型了,结果挂了20分-- 以后 ...
- 数组排列组合问题——BACKTRACKING
BACKTRACKING backtracking(回溯法)是一类递归算法,通常用于解决某类问题:要求找出答案空间中符合某种特定要求的答案,比如eight queens puzzle(将国际象棋的八个 ...
- LEETCODE 150题吐血大整理
原文地址:http://bowang.name/leetcode-150/ 断断续续刷了三个月的leetcode,近日终于大功告成.这里把所有题目按难易程度分了下类,并作了简要说明.难度等级纯粹是凭主 ...
- 【LeetCode】Palindrome Partitioning 解题报告
[题目] Given a string s, partition s such that every substring of the partition is a palindrome. Retur ...
- Palindrome Partitioning
题目:Given a string s, partition s such that every substring of the partition is a palindrome. Return ...
- [Lintcode]136. Palindrome Partitioning /[Leetcode]131. Palindrome Partitioning
136. Palindrome Partitioning / 131. Palindrome Partitioning 本题难度: Medium Topic: Search DFS Descripti ...
- [Leetcode Week13]Palindrome Partitioning
Palindrome Partitioning 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/palindrome-partitioning/desc ...
最新文章
- 全民K歌内容挖掘与召回
- Grails 1.2参考文档速读(15):验证
- cpu性能测试软件 国际象棋,国际象棋、科学计算,整机性能测试
- C++ IO类(3) 文件流
- Linux的实际操作:文件目录类的实用指令(ln history)
- 开发测试服务器配置信息,node服务端中台实现及开发测试生产环境配置
- urllib、requests库整理
- mysql 停数据库_mysql数据库突然停了
- oracle运维dba面试题,一份DBA面试题目---亲身经历
- MVVM 架构解析及 Jetpack 架构组件的使用
- Freeswitch 结合AIO100语音网关 发送短信
- 1039:判断数正负(测试已通过)
- UOJ #34 多项式乘法
- CTB全球创新大挑战组队中 全新课题火热来袭
- FPGA通信第一篇--USB2.0
- php期末作业报告,期末作业(最终版).php
- 一文搞懂人脸识别那点事---人脸识别方案summary
- 小白java环境变量配置
- 讲几个关于程序员笑话!
- 表单验证:文字输入不超过8个汉字或者16个字符
热门文章
- 大学python用什么教材-数据结构 Python语言描述 大学教材
- python自学免费课堂-python自学——文件打开
- 学习python需要什么基础-学习python需要什么基础吗?老男孩Python
- python学习手册中文版免费下载-Python学习手册(第3版)
- yolov5 v3.0训练报错: torch.nn.modules.module.ModuleAttributeError: ‘BatchNorm2d‘ object has no attribute
- pip镜像源永久设置成国内镜像源,提升下载速度
- 如何更改linux文件的拥有者及用户组(chown和chgrp)
- Shell中的循环语句for、while、until实例讲解
- Leader/Follower多线程网络模型介绍
- RGB转YUV 各种库的性能比较