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

bzoj Luogu

你要用ATGC四个字母用两种操作拼出给定的串:

1.将其中一个字符放在已有串开头或者结尾。

2.将已有串复制,然后reverse,再接在已有串的头部或者尾部。

一开始已有串为空。求最少操作次数。

len<=100000

题解时间

一个非空串经过一次操作2之后一定是一个偶回文串。

所以考虑建出PAM之后dp。

由于只有偶回文串可以通过操作2产生,所以只有偶回文串参与dp。

对于PAM上一个点 $ x $ :

  • 如果这个串去掉两头一个字母之后的串 $ y $ 非空,那么很明显 $ x $ 可以由 $ y $ 在操作2之前先加上这个字母获得, $ dp[x]=dp[y]+1 $ 。

  • 而如果 $ y $ 为空,那么需要至少两次操作, $ dp[x]=2 $ 。

  • $ x $ 可以由长度不超过 $ len/2 $ 的后缀回文串延长复制得来,倍增跳fail找到第一个长度不超过 $ len/2 $ 的串 $ y $ , $ dp[x]=dp[y]+(len[x]/2-len[y])+1 $ 。

#include<bits/stdc++.h>
using namespace std;
namespace RKK
{
const int N=100011;
char str[N];int n;
int cc(char ch)
{
switch(ch)
{
case 'A':return 0;
case 'G':return 1;
case 'C':return 2;
case 'T':return 3;
default:return 114514;
}
}
queue<int> q;
struct remilia{int tranc[4],len,fail;void set(){memset(this,0,24);}};
struct sakuya
{
remilia p[N];
int size,fin;
int fa[N][20];
int dp[N];
void set()
{
p[0].set(),p[1].set();
p[0].len=0,p[1].len=-1;
p[0].fail=p[1].fail=1;
memset(dp,0,(size+1)*sizeof(int));
size=fin=1;
}
sakuya(){size=fin=1;this->set();}
int match(char *s,int i,int px){return s[i-p[px].len-1]==s[i];}
void ins(char *s,int i)
{
int ch=cc(s[i]);
int npx,lpx,lpy;
lpx=fin;
while(!match(s,i,lpx)) lpx=p[lpx].fail;
if(!p[lpx].tranc[ch])
{
npx=++size;p[npx].set();
p[npx].len=p[lpx].len+2;
lpy=p[lpx].fail;
while(!match(s,i,lpy)) lpy=p[lpy].fail;
p[npx].fail=p[lpy].tranc[ch];
p[lpx].tranc[ch]=npx;
}
fin=p[lpx].tranc[ch];
}
int find(int x)
{
int l=p[x].len/2;
for(int k=19;k>=0;k--)if(p[fa[x][k]].len>l) x=fa[x][k];
while(p[x].len&1||p[x].len>l) x=fa[x][0];
return x;
}
void work()
{
for(int i=0;i<=size;i++) fa[i][0]=p[i].fail;
for(int k=1;k<20;k++)for(int i=0;i<=size;i++) fa[i][k]=fa[fa[i][k-1]][k-1];
dp[0]=0;for(int i=0;i<4;i++)if(p[0].tranc[i]) dp[p[0].tranc[i]]=2,q.push(p[0].tranc[i]);
int ans=n;
while(!q.empty())
{
int x=q.front();q.pop();
int f=find(x);
dp[x]=min(dp[x],dp[f]+p[x].len/2-p[f].len+1);
ans=min(ans,n-p[x].len+dp[x]);
for(int i=0;i<4;i++)if(p[x].tranc[i]) dp[p[x].tranc[i]]=dp[x]+1,q.push(p[x].tranc[i]);
}
printf("%d\n",ans);
}
}pam;
int TAT;
int Iris()
{
scanf("%d",&TAT);
while(TAT--)
{
scanf("%s",str+1),n=strlen(str+1);
for(int i=1;i<=n;i++) pam.ins(str,i);
pam.work();
pam.set();
}
return 0;
}
}
int main(){return RKK::Iris();}

bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)的更多相关文章

  1. BZOJ 4044 Luogu P4762 [CERC2014]Virus Synthesis (回文自动机、DP)

    好难啊..根本不会做..基本上是抄Claris... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4044 (luogu) ...

  2. luogu P4762 [CERC2014]Virus synthesis (回文自动机)

    大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...

  3. BZOJ 4044 Virus synthesis (回文自动机+dp)

    题目大意: 你可以在一个串的开头或者末尾加入一个字符,或者把当前整个串$reverse$,然后接在前面或者后面,求达到目标串需要的最少操作次数 对目标串建出$PAM$ 定义$dp[x]$表示当前在回文 ...

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

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

  5. bzoj 4044: Virus synthesis 回文自动机

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

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

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

  7. bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)

    bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...

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

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

  9. 洛谷P4762 [CERC2014]Virus synthesis(回文自动机+dp)

    传送门 回文自动机的好题啊 先建一个回文自动机,然后记$dp[i]$表示转移到$i$节点代表的回文串的最少的需要次数 首先肯定2操作越多越好,经过2操作之后的串必定是一个回文串,所以最后的答案肯定是由 ...

随机推荐

  1. Solution -「AGC 029E」「AT 4504」Wandering TKHS

    \(\mathcal{Description}\)   Link.   给一棵 \(n\) 个点的树,从某个点出发,遍历时必须走到已经走过的连通块所邻接的编号最小的结点.求从每个点出发,走到 \(1\ ...

  2. .Net Core Aop之IActionFilter

    一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...

  3. 实战 | 关于随手一点就发现XSS漏洞这件事

    起因 今天正在做一个项目时,需要找一个云接码平台接码去登录系统.当我随手从百度找了一个接码平台时,一个偶然的发现,有了今天这篇文章. 正文 当我进入这个接码平台随便找了个手机号,然后等了好几分钟都没啥 ...

  4. [题解]第十一届北航程序设计竞赛预赛——I.神奇宝贝大师

    题目描述 一张n*m的地图,每个格子里面有一定数量的神奇宝贝,求一个最优位置,使得所有神奇宝贝到该位置的曼哈顿距离最小. 一共有T组数据,每组数据包含两行,第一行是n和m(1<=n,m<= ...

  5. [数据生成器]UVA10054 The Necklace

    应吴老师之邀,写了个数据生成器. 目前这个数据生成器可以保证生成的数据都是合法的,且效率也还不错.只是在建立普通连通图的时候zyy偷懒了,直接把所有点串起来从而保证图的连通.如果有大神有更好的方法请不 ...

  6. 在 Linux 下确认 NTP 是否同步的方法

    NTP 意即网络时间协议Network Time Protocol,它通过网络同步计算机系统之间的时钟.NTP 服务器可以使组织中的所有服务器保持同步,以准确时间执行基于时间的作业.NTP 客户端会将 ...

  7. 【C# 调试】.net中的 .pdb文件是什么,有什么用

    mscn:在 Visual Studio 调试器(C#)中指定符号 (.pdb) 和源文件 PDB全称Program Database,程序数据库 ( .pdb) 文件(也称为符号文件)将项目源代码中 ...

  8. python+pytest(3)-接口测试一般流程及方法

    首先我们要明确,通常所接口测试其实就属于功能测试,主要校验接口是否实现预定的功能,虽然有些情况下可能还需要对接口进行性能测试.安全性测试. 在学习接口自动化测试之前,我们先来了解手工接口测试怎样进行. ...

  9. 分布式 PostgreSQL - Citus 架构及概念

    节点 Citus 是一种 PostgreSQL 扩展,它允许数据库服务器(称为节点)在"无共享(shared nothing)"架构中相互协调.这些节点形成一个集群,允许 Post ...

  10. tar包压缩时相对路径问题

    一.问题描述 现在有一个需求,不知道该如何才能实现压缩: tar -czvf /home/futong/test/logs.tar.gz /home/futong/test/logs 打开压缩包发现 ...