BZOJ 4044 Virus synthesis (回文自动机+dp)
题目大意:
你可以在一个串的开头或者末尾加入一个字符,或者把当前整个串$reverse$,然后接在前面或者后面,求达到目标串需要的最少操作次数
对目标串建出$PAM$
定义$dp[x]$表示当前在回文树的x节点,拼凑出这个节点表示的回文串所需要的最小操作次数
$fa_{x}$表示沿着树边指向它的父亲,$pre_{x}$表示它的$fail$指针
如果它是奇回文串,一定不能被翻转得到,所以开头结尾各需要加上一个字符,$dp[x]=dp[fa_{x}]+2$
如果它是偶回文串,可以被翻转得到
1.要么是在上次翻转之前先添加一个字符,再翻转得到,$dp[x]=dp[fa_{x}]+1$
2.要么是在这次进行翻转,需要保证被翻转的串长度不大于$dep[x]/2$
可以在回文树上倍增跳$pre$,找到$x$的一个长度不大于$dep[x]/2$的回文后缀所在节点$y$
只需要找后缀的情况即可,其他的情况会被合并到情况一里
剩下的部分也要被暴力地填上,那么$dp[x]=dp[y]+dep[x]/2-dep[y]+1$
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 100100
#define S1 (N1<<1)
#define ll long long
#define uint unsigned int
#define rint register int
#define dd double
#define il inline
#define inf 0x3f3f3f3f
using namespace std; int len,T;
inline int idx(char x)
{
if(x=='A') return ;
if(x=='C') return ;
if(x=='G') return ;
if(x=='T') return ;
}
char str[N1];
int lg[N1];
namespace PAM{
int trs[N1][],pre[N1],dep[N1],fa[N1],dp[N1],la,tot;
int ff[N1][];
void init()
{
tot++;
memset(trs,,tot**),memset(pre,,tot*);
memset(ff,,tot**),memset(fa,,tot*);
memset(dp,,tot*),memset(dep,,tot*);
la=tot=,dep[]=-;pre[]=pre[]=;
}
int chk(char *str,int i,int p){return str[i-dep[p]-]!=str[i]?:;}
void insert(char *str,int i)
{
int p=la,np,fp,c=idx(str[i]);
while(chk(str,i,p)) p=pre[p];
if(!trs[p][c])
{
np=++tot;
dep[np]=dep[p]+;
fp=pre[p];
while(chk(str,i,fp)) fp=pre[fp];
pre[np]=trs[fp][c];
trs[p][c]=np;
fa[np]=p;
}
la=trs[p][c];
}
int solve()
{
int i,j,x,ans=len,de;
ff[][]=ff[][]=ff[][]=ff[][]=;
for(i=;i<=tot;i++) ff[i][]=i,ff[i][]=pre[i];
for(j=;j<=;j++)
for(i=;i<=tot;i++)
ff[i][j]=ff[ ff[i][j-] ][j-];
dp[]=,dp[]=-;
for(i=;i<=tot;i++)
{
x=i;
dp[i]=dp[fa[i]]+((dep[i]&)?:);
if((dep[i]&)) continue;
for(j=lg[dep[i]];j>=;j--)
if(dep[ff[x][j]]>=dep[i]/) x=ff[x][j];
if(dep[x]>dep[i]/) x=pre[x];
dp[i]=min(dp[i],dp[x]++dep[i]/-dep[x]);
ans=min(ans,len-dep[i]+dp[i]);
}
return ans;
}
}; int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",str+);
len=strlen(str+);
int i;
for(lg[]=,i=;i<=len;i++) lg[i]=lg[i>>]+;
PAM::init();
for(i=;i<=len;i++) PAM::insert(str,i);
printf("%d\n",PAM::solve());
}
return ;
}
BZOJ 4044 Virus synthesis (回文自动机+dp)的更多相关文章
- bzoj 4044: Virus synthesis 回文自动机
题目大意: 你要用ATGC四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空.求最少操作次数. le ...
- bzoj 4044 Virus synthesis - 回文自动机 - 动态规划
题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...
- bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)
bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp) bzoj Luogu 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符 ...
- BZOJ 4044 Luogu P4762 [CERC2014]Virus Synthesis (回文自动机、DP)
好难啊..根本不会做..基本上是抄Claris... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4044 (luogu) ...
- [BZOJ4044]Virus synthesis 回文自动机的DP
4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec Memory Limit: 128 MB Description Viruses are us ...
- luogu P4762 [CERC2014]Virus synthesis (回文自动机)
大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...
- bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)
bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...
- bzoj 4044: [Cerc2014] Virus synthesis【回文自动机+dp】
建回文自动机,注意到一个回文串是可以通过一个长度小于等于这个串长度的一半的回文串添上一些字符然后复制得到的,也就是在自动机上向fa走,相当于treedp 每次都走显然会T,记录一个up,指向祖先中最下 ...
- [CERC2014]Virus synthesis【回文自动机+DP】
[CERC2014]Virus synthesis 初始有一个空串,利用下面的操作构造给定串 SS . 1.串开头或末尾加一个字符 2.串开头或末尾加一个该串的逆串 求最小化操作数, \(|S| \l ...
随机推荐
- LAMP环境下,通过网页url获取gb2312编码中文命名的下载资源方法
最近有个功能, 要求获取中文命名的.zip压缩文件,我准备直接采用网页url填写压缩文件地址的方式获取下载资源, 但问题是 我们的linux系统和php编程环境都是采用的zh_GB2312编码, 而浏 ...
- Elasticsearch 入门 - 基本概念
NRT Elasticsearch 是一个 接近实时 的搜索平台.这意味着从你索引文档到其可以被搜索中间存在着一个轻微的延迟(通常为1秒钟). Cluster 一个或多个节点的完整数据.聚合索引和搜索 ...
- 基于【SpringBoot】的微服务【Jenkins】自动化部署
最近,也是抽空整理了一些在工作中积累的经验,通过博客记录下来分享给大家,希望能对大家有所帮助: 一.关于自动化部署 关于自动化部署的优点,我就不在这里赘述了:只要想想手工打包.上传.部署.重启的种种, ...
- HDU3236 Gift Hunting
/* HDU3236 Gift Hunting http://acm.hdu.edu.cn/showproblem.php?pid=3236 dp 滚动数组 * * */ #include <c ...
- Codeforces Round #136 (Div. 1) B. Little Elephant and Array
B. Little Elephant and Array time limit per test 4 seconds memory limit per test 256 megabytes input ...
- 回车登录(支持IE 和 火狐等浏览器)
$("body").keydown(function(e){ var curKey = e.which; if(curKey == 13){ $("#Btn_login& ...
- kettle 使用excel模板导出数据
通过excel进行高速开发报表: 建设思路: 1.首先制订相关的execl模板. 2.通过etl工具(kettle)能够高速的 将数据库中的数据按excel模板导出成新的excel就可以. 当中ket ...
- 0x04 二分
二分.三分其实没什么.. 但是真心觉得市面上的朴素二分打法千奇百怪,假如是像我的标程应该是比较稳妥的,然而poj2018那题(前缀和又想起来了)是向下取整,精度有点问题(经常拍出一些什么xxx.999 ...
- Oracle 优化和性能调整
分析评价Oracle数据库性能主要有数据库吞吐量.数据库用户响应时间两项指标.数据库用户响应时间又可以分为系统服务时间和用户等待时间两项,即: 数据库用户响应时间=系统服务时间+用户等待时间 因此 ...
- linux下关于IPC(进程间通信)
linux下进程间通信的主要几种方式 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许 ...