bzoj 4044: [Cerc2014] Virus synthesis【回文自动机+dp】
建回文自动机,注意到一个回文串是可以通过一个长度小于等于这个串长度的一半的回文串添上一些字符然后复制得到的,也就是在自动机上向fa走,相当于treedp
每次都走显然会T,记录一个up,指向祖先中最下长度符合要求的回文后缀,这样每次找最多跳一次,所以是O(n)的,还有child的清空动态的做,也就是新建一个点清空一个点
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100005;
int T,n,ch[N][5],fa[N],up[N],dis[N],f[N],con,la,mp[205],ans;
char s[N];
void clr(int x)
{
ch[x][0]=ch[x][1]=ch[x][2]=ch[x][3]=0;
}
void ins(int c,int w)
{
int p=la;
for(;s[w-1-dis[p]]!=s[w];p=fa[p]);
if(!ch[p][c])
{
int cur=++con,q=fa[p];
dis[cur]=f[cur]=dis[p]+2,clr(cur);
for(;s[w-dis[q]-1]!=s[w];q=fa[q]);
fa[cur]=ch[q][c];
if(dis[cur]<=2)
up[cur]=fa[cur];
else
{
q=up[p];
for(;s[w-dis[q]-1]!=s[w]||2*(dis[q]+2)>dis[cur];q=fa[q]);
up[cur]=ch[q][c];
}
ch[p][c]=cur;
if((dis[cur]&1)==0)
{
f[cur]=min(f[cur],f[up[cur]]+(dis[cur]/2-dis[up[cur]])+1);
if(p>=2)
f[cur]=min(f[cur],f[p]+1);
}
else
f[cur]=min(f[cur],min(dis[cur]-dis[fa[cur]]+f[fa[cur]],f[p]+2));
}
la=ch[p][c];
}
int main()
{
scanf("%d",&T);
mp['A']=0,mp['T']=1,mp['G']=2,mp['C']=3;
while(T--)
{
scanf("%s",s+1);
n=strlen(s+1);
ans=n,con=1,la=0,dis[0]=0,dis[1]=-1,fa[0]=1,s[0]=-1;
clr(0),clr(1);
for(int i=1;i<=n;i++)
ins(mp[s[i]],i);
for(int i=2;i<=con;i++)
ans=min(ans,n-dis[i]+f[i]);
printf("%d\n",ans);
}
return 0;
}
bzoj 4044: [Cerc2014] Virus synthesis【回文自动机+dp】的更多相关文章
- 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) ...
- BZOJ 4044 Virus synthesis (回文自动机+dp)
题目大意: 你可以在一个串的开头或者末尾加入一个字符,或者把当前整个串$reverse$,然后接在前面或者后面,求达到目标串需要的最少操作次数 对目标串建出$PAM$ 定义$dp[x]$表示当前在回文 ...
- luogu P4762 [CERC2014]Virus synthesis (回文自动机)
大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...
- [BZOJ4044]Virus synthesis 回文自动机的DP
4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec Memory Limit: 128 MB Description Viruses are us ...
- bzoj 4044: Virus synthesis 回文自动机
题目大意: 你要用ATGC四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空.求最少操作次数. le ...
- bzoj 4044 Virus synthesis - 回文自动机 - 动态规划
题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...
- bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)
bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...
- [CERC2014]Virus synthesis【回文自动机+DP】
[CERC2014]Virus synthesis 初始有一个空串,利用下面的操作构造给定串 SS . 1.串开头或末尾加一个字符 2.串开头或末尾加一个该串的逆串 求最小化操作数, \(|S| \l ...
随机推荐
- 浅析怎样学好C语言
今天,我能够自称是一个混IT的人,并能以此谋生,将来大家能一次谋生.都要感谢两个人:克劳德.香农和约翰.冯.诺依曼,是他们发现了全部的数字化信息,不论是一段程序,一封email.一部电影都是用一连串的 ...
- SpringBoot学习之启动报错【This application has no explicit mapping for /error.....】
今天做SpringBoot小例子,在请求controller层的时候出现如下问题. Whitelabel Error Page This application has no explicit map ...
- 关于CAShapeLayer
关于CAShapeLayer 内容大纲: CAShapeLayer简介 贝塞尔曲线与CAShapeLayer的关系 strokeStart和strokeEnd 动画 用CAShapeLayer实现进度 ...
- STM32唯一身份识别ID(器件电子签名)的读取以及芯片Flash大小读取
每个STM32有一个独立的ID,这个ID可以用来: 产品唯一的身份标识的作用: ● 用来作为序列号(例如USB字符序列号或者其他的终端应用): ● 用来作为密码,在编写闪存时,将此唯一 ...
- CodeChef - COUNTARI FTT+分块
Arithmetic Progressions Given N integers A1, A2, …. AN, Dexter wants to know how many ways he can ch ...
- pyspark mongodb yarn
from pyspark.sql import SparkSession my_spark = SparkSession \ .builder \ .appName("myApp" ...
- kill 挂起 Apache Web Server
[root@hadoop1 ~]# kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8 ...
- p1694猴子 并查集
有n只猴子,第一只尾巴挂在树上,剩下的n-1只,要么被其他的猴子抓住,要么抓住了其他的猴子,要么两者均有. 当然一只猴子最多抓两只另外的猴子,因为只有两只猴爪子嘛.现在给出这n只猴子抓与被抓的信息,并 ...
- js截取小数点后面2位
1.substr var str = "Hello world!"; document.write(str.substr(3)); 输出:lo world! var str = & ...
- html5--6-16 CSS3中的文字与字体
html5--6-16 CSS3中的文字与字体 中文字体包很大,少量字体的话可以有其它方法. 有字库-首页-全球第一中文web font(在线字体)服务平台.web font.webfont.在线字体 ...