题意

真是道回文自动机好题。

首先考虑答案必定是一个回文串+剩余部分的形式,因此可以建出回文自动机,之后考虑每个长度为偶数的回文串。

对于一个长度为偶数的回文串,设它在回文自动机上对应的节点为\(x\),我们对于每个\(x\)求出\(trans_x\)表示x的最长后缀回文串,满足\(len_{trans_x}\leqslant len_x/2\)。

之后设\(f_x\)表示\(x\)拼成\(x\)这个串的最小代价,我们从\(0\)(偶根)出发进行\(bfs\),中途计算\(f_x\)。

对于\(f_x\):

初值肯定是自身长度\(f_x=len_x\)。

如果存在一条边\((x,y)\),那么\(f_y=f_x+1\),因为我们可以在拼\(x\)时还没进行\(2\)操作时向\(x\)后面填一个字符,使其进行\(2\)操作后变为\(y\)。

同时\(f_x=min(f_x,f_{trans_x}+1+lem_x/2-len_{trans_x})\),即我们可以从\(trans_x\)变过来。

对于每个\(x\),它对答案的贡献是\(n-len_x+f_x\),\(n\)是字符串长度。

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int inf=1e9;
int T,n,tot,last,ans;
int fail[maxn],len[maxn],trans[maxn],f[maxn];
int ch[maxn][5];
char s[maxn];
inline int change(char c)
{
if(c=='A')return 1;
if(c=='G')return 2;
if(c=='C')return 3;
if(c=='T')return 4;
return 2333;
}
inline void init()
{
for(int i=0;i<=tot;i++)
for(int j=1;j<=4;j++)
ch[i][j]=0;
fail[0]=1;len[1]=-1;
tot=1;last=0;
}
inline int getfail(int x,int pos)
{
while(s[pos-len[x]-1]!=s[pos])x=fail[x];
return x;
}
inline void add(int c,int pos)
{
int p=getfail(last,pos);
if(!ch[p][c])
{
int q=++tot,tmp;len[q]=len[p]+2;
tmp=getfail(fail[p],pos);
fail[q]=ch[tmp][c];ch[p][c]=q;
if(len[q]<=2)trans[q]=fail[q];
else
{
tmp=trans[p];
while(s[pos-len[tmp]-1]!=s[pos]||((len[tmp]+2)<<1)>len[q])tmp=fail[tmp];
trans[q]=ch[tmp][c];
}
}
last=ch[p][c];
}
inline void solve()
{
queue<int>q;
for(int i=2;i<=tot;i++)f[i]=len[i];
for(int i=1;i<=4;i++)if(ch[0][i])q.push(ch[0][i]);
while(!q.empty())
{
int x=q.front();q.pop();
f[x]=min(f[x],f[trans[x]]+1+len[x]/2-len[trans[x]]);
ans=min(ans,n-len[x]+f[x]);
for(int i=1;i<=4;i++)
{
if(!ch[x][i])continue;
int y=ch[x][i];
f[y]=min(f[y],f[x]+1);
q.push(y);
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",s+1);n=strlen(s+1);
s[0]='#';
init();
for(int i=1;i<=n;i++)add(change(s[i]),i);
ans=n;solve();
printf("%d\n",ans);
}
return 0;
}

P4762 [CERC2014]Virus synthesis的更多相关文章

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

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

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

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

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

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

  4. luogu_4762: [CERC2014]Virus synthesis

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

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

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

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

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

  7. bzoj4044 [Cerc2014] Virus synthesis

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

  8. [CERC2014] Virus synthesis

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

  9. bzoj 4044: [Cerc2014] Virus synthesis【回文自动机+dp】

    建回文自动机,注意到一个回文串是可以通过一个长度小于等于这个串长度的一半的回文串添上一些字符然后复制得到的,也就是在自动机上向fa走,相当于treedp 每次都走显然会T,记录一个up,指向祖先中最下 ...

随机推荐

  1. Git实战指南----跟着haibiscuit学Git(第三篇)

    笔名:  haibiscuit 博客园: https://www.cnblogs.com/haibiscuit/ Git地址: https://github.com/haibiscuit?tab=re ...

  2. Jsf中进度条的用法

    Jsf中进度条的用法 前端页面 <!-- 进度条 --> <p:progressBar widgetVar="pbAjax" ajax="true&qu ...

  3. [转]为何选择 Flink

    本文转自:https://www.ituring.com.cn/book/tupubarticle/23229 第 1 章 为何选择 Flink 人们对某件事的正确理解往往来自基于有效论据的结论.要获 ...

  4. android 引入一个布局库后该有的操作

    背景 引入一个布局库:com.zhy:percent-support-extends 然后sync now 成功了,也就是同步成功了. 然而开始使用的时候报告了: The following clas ...

  5. 页面中加入地图map

    1.首先要有密钥AK ,可以自己注册获取或复制别人的 .搜索百度地图API (http://lbsyun.baidu.com/apiconsole/key) 2.地图示例 <head> & ...

  6. 团队项目之Scrum7

    小组:BLACK PANDA 时间:2019.11.27 每天举行站立式会议 提供当天站立式会议照片一张 2 昨天已完成的工作 2 内容展示 根据三大板块进行分类: 电影. 音乐以及摄影 今天计划完成 ...

  7. ORA-27468: ""."" is locked by another process

    You have a scheduler job that generated an error. When the error occurred, you attempted to disable ...

  8. 数理统计(二)——Python中的概率分布API

    数理统计(二)——Python中的概率分布API iwehdio的博客园:https://www.cnblogs.com/iwehdio/ 数理统计中进行假设检验需要查一些分布的上分位数表.在scip ...

  9. DWG文件怎么转换成PDF格式

    在CAD中,设计师们绘制的图纸都是以dwg文件来进行保存的.Dwg文件是不能够直接进行打开查看的,就需要将其格式进行转换一下.将dwg文件转换为PDF格式的进行查看.那具体要怎么来进行操作呢?下面小编 ...

  10. PostgreSQL 中字段类型varchar

    PostgreSql数据库中varchar类型与sql server中字段用法有差别,PostgreSql中如果字段设置为varchar类型长度为10,则无论存字母.数字或其它符号,长度最大为10个, ...