Virus synthesis

初始有一个空串,利用下面的操作构造给定串 S 。

  1. 串开头或末尾加一个字符
  2. 串开头或末尾加一个该串的逆串

求最小化操作数, ∣S∣≤105

题解

显然应该多使用操作2——翻转复制。

建出 S 的回文自动机,设 dp(i) 表示构造节点 i 表示回文串所需最少操作次数。

ans=min {dp(i)+n-leni}

若 i 能转移到 j,则 dp(j)=dp(i)+1。因为 i 是回文串,所以 i 一定是由翻转复制得到的。在这之前一步加上 j 的字符就是这个转移的意义。

回文自动机维护出 half,那么 dp(i)=dp(halfi)+leni/2-lenhalfi+1。这个转移意义很明显。

发现转移需要回文自动机的 DAG 的更新顺序,所以使用队列维护。

时间复杂度 \(O(|S|)\)。

co int N=100000+10;
char s[N];
il int idx(char c){
switch(c){
case 'A':return 0;
case 'G':return 1;
case 'C':return 2;
default:return 3;
}
} int last,tot;
int ch[N][4],fa[N],len[N],half[N]; int get_fa(int x,int i){
while(s[i-len[x]-1]!=s[i]) x=fa[x];
return x;
}
void extend(int i){
int p=get_fa(last,i);
int x=ch[p][idx(s[i])];
if(!x){
x=++tot,memset(ch[x],0,sizeof ch[x]);
fa[x]=ch[get_fa(fa[p],i)][idx(s[i])];
len[x]=len[p]+2;
ch[p][idx(s[i])]=x;
if(len[x]==1) half[x]=0;
else{
int q=half[p];
while(s[i-len[q]-1]!=s[i]||(len[q]+2)<<1>len[x]) q=fa[q];
half[x]=ch[q][idx(s[i])];
}
}
last=x;
} int dp[N];
void real_main(){
last=tot=1;
memset(ch[0],0,sizeof ch[0]),memset(ch[1],0,sizeof ch[1]);
fa[0]=fa[1]=1,len[1]=-1; scanf("%s",s+1);int n=strlen(s+1);
for(int i=1;i<=n;++i) extend(i); dp[0]=1; // ""->"a,a" : cost=2
for(int i=2;i<=tot;++i) dp[i]=len[i];
deque<int> q(1,0);
int ans=n;
while(q.size()){
int p=q.front();q.pop_front();
for(int c=0;c<4;++c){
int x=ch[p][c];
if(!x) continue;
dp[x]=dp[p]+1;
int y=half[x];
dp[x]=min(dp[x],dp[y]+(len[x]>>1)-len[y]+1);
ans=min(ans,dp[x]+n-len[x]);
q.push_back(x);
}
}
printf("%d\n",ans);
}
int main(){
for(int T=read<int>();T--;) real_main();
return 0;
}

LG4762 Virus synthesis的更多相关文章

  1. [BZOJ4044]Virus synthesis 回文自动机的DP

    4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec  Memory Limit: 128 MB Description Viruses are us ...

  2. luogu_4762: [CERC2014]Virus synthesis

    洛谷_4762:[CERC2014]Virus synthesis 题目描述: 初始有一个空串,利用下面的操作构造给定串\(S\).\(len(S)\leq10^5\) 1: 串开头或末尾加一个字符. ...

  3. [CERC2014]Virus synthesis【回文自动机+DP】

    [CERC2014]Virus synthesis 初始有一个空串,利用下面的操作构造给定串 SS . 1.串开头或末尾加一个字符 2.串开头或末尾加一个该串的逆串 求最小化操作数, \(|S| \l ...

  4. bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)

    bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp) bzoj Luogu 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符 ...

  5. bzoj4044 [Cerc2014] Virus synthesis

    回文自动机上dp f[x]表示形成x代表的回文串所需的最小步数, 若len[x]为奇数,f[x]=len[x],因为即使有更优的,也是直接添加,没有复制操作,那样就不用从x转移了. 若len[x]为偶 ...

  6. [CERC2014] Virus synthesis

    设f[i]为形成极长回文串i的最小操作数.答案为min f[i]+n-len[i]. 在不形成偶回文的情况下形成奇回文的最小操作数为该串长度.可以不考虑(但ans赋为len). 正确性基于: 1)奇. ...

  7. Codeforces Gym100543G Virus synthesis 字符串 回文自动机 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF-100543G.html 题目传送门 - CF-Gym100543G 题意 你可以对一个字符串进行以下两种操 ...

  8. bzoj 4044 Virus synthesis - 回文自动机 - 动态规划

    题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...

  9. Bzoj4044 Virus synthesis

    题意 你要用 \(ATGC\) 四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后 \(reverse\) ,再接在已有串的头部或者尾部 一开始已有串为空.求最 ...

随机推荐

  1. 【转】Fuel-openstack的搭建(二)

    原文链接:https://blog.csdn.net/qq_35180983/article/details/82181525 部署Openstack 3.1 登陆 登陆http://10.20.0. ...

  2. chamfer_pcd

    import tensorflow as tf import numpy as np def distance_matrix(array1, array2): """ a ...

  3. 开发板与pc之间文件传输:kermit and lrzsz

    imx6开发板与pc机之间通过串口传输文件步骤: 1. 安装好kermit并可以使用 2. 交叉编译lrzsz开源软件并把可执行程序lrz lsz拷贝到开发板 2.1 下载并解压lrzsz-0.12. ...

  4. Python之 random 模块

    #!/usr/bin/env python # -*- coding:utf8 -*- import random ''' 如果想要随机的内容的话,就可以使用这个模块来完成 ''' ######### ...

  5. Django重新添加字段然后迁移给定默认值依然迁移不生效

    1.将对应app下的migrations文件夹下面的除了__init__.py文件外全部删除 2.delete from django_migrations where app='当前模型的app名称 ...

  6. Linux进程的五个段

    目录 数据段 代码段 BSS段 堆(heap) 栈 数据段 用来存放可执行文件中已初始化的全局变量,换句话说就是存放程序静态分配的变量和全局变量: 代码段 代码段是用来存放可执行文件的操作指令,也就是 ...

  7. Java线程的等待与唤醒完整示例代码

    项目结构: 资源类: 输入线程:  输出线程: 测试: 人妖问题发生: 线程安全问题的解决方法: 调用Object的wait()和notify()方法时需注意:必须是锁对象方可调用,否则将抛出无效的监 ...

  8. 解决跟Docker私有仓库登陆,推送,拉取镜像出现的报错

    出现问题:Error response from daemon: Get https://192.168.186.120/v1/users/: dial tcp 192.168.186.120:443 ...

  9. Unity的学习笔记(XLua的初学用法并在lua中使用unity周期函数)

    自己最近也在研究怎么用lua控制UI,然后看着网上介绍,决定选用XLua,毕竟TX爸爸出的,有人维护,自己琢磨着怎么用,于是弄出来一个能用的作为记录. 当然,XLua主要是用于热更新,我自己是拿来尝试 ...

  10. Jboss部署war以及获取Resource的真实路径

    Jboss部署war以及获取Resource的真实路径 最近在将一个SpringBoot项目打成war包部署到Jboss中,中途遇到一些问题记录. Jboss上部署war 普通的SpringBoot项 ...