题意

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

  1. 将其中一个字符放在已有串开头或者结尾
  2. 将已有串复制,然后 \(reverse\) ,再接在已有串的头部或者尾部

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

\(len\le100000\)

Sol

首先有个结论

每次形成偶数长度回文串的最后一步一定是操作 \(2\)

那么考虑一个 \(DP\)

设 \(f[i]\) 表示形成 \(i\) 表示的字符串需要的最少步数

可以去掉首和尾转移来,可以由它的一个前缀或者后缀转移来

如果是个偶数长度的字符串

可以由某个长度小于等于它一半的字符串增长到它的长度后翻倍而来

可以由它去掉首尾的串一步转移而来,因为去掉首位仍然是偶数长度而且形成偶数长度回文串的最后一步一定是操作 \(2\)

那么直接用回文树实现

求某个长度小于等于它一半的字符串直接建树的时候暴力跳一下(雾

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll; IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} const int maxn(1e5 + 5); int f[maxn], son[4][maxn], trans[666], half[maxn], len[maxn], fa[maxn], num[maxn], tot, last, pre[maxn];
char s[maxn]; IL void Init(){
for(RG int i = 0; i <= tot; ++i){
len[i] = fa[i] = half[i] = 0;
for(RG int j = 0; j < 4; ++j) son[j][i] = 0;
}
fa[0] = fa[1] = 1, len[1] = -1, tot = 1, last = 0;
} IL void Extend(RG int pos, RG int c){
RG int p = last;
while(s[pos - len[p] - 1] != s[pos]) p = fa[p];
if(!son[c][p]){
RG int np = ++tot, q = fa[p];
while(s[pos - len[q] - 1] != s[pos]) q = fa[q];
len[np] = len[p] + 2, fa[np] = son[c][q];
son[c][p] = np, pre[np] = p;
if(s[pos - len[half[p]] - 1] == s[pos]) half[np] = son[c][half[p]];
else half[np] = fa[np];
while((len[half[np]] << 1) > len[np]) half[np] = fa[half[np]];
}
last = son[c][p];
} int main(){
trans['C'] = 1, trans['G'] = 2, trans['T'] = 3;
for(RG int t = Input(), n = 0; t; --t){
Init(), scanf(" %s", s + 1), n = strlen(s + 1);
for(RG int i = 1; i <= n; ++i) Extend(i, trans[s[i]]);
RG int ans = n;
for(RG int i = 2; i <= tot; ++i){
f[i] = min(len[i], f[fa[i]] + len[i] - len[fa[i]]);
if(len[i] & 1) f[i] = min(f[pre[i]] + 2, f[i]);
else{
f[i] = min(f[i], pre[i] ? f[pre[i]] + 1 : 2);
f[i] = min(f[i], f[half[i]] + (len[i] >> 1) - len[half[i]] + 1);
}
ans = min(ans, f[i] + n - len[i]);
}
printf("%d\n", ans);
}
return 0;
}

Bzoj4044 Virus synthesis的更多相关文章

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

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

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

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

  3. luogu_4762: [CERC2014]Virus synthesis

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

  4. LG4762 Virus synthesis

    Virus synthesis 初始有一个空串,利用下面的操作构造给定串 S . 串开头或末尾加一个字符 串开头或末尾加一个该串的逆串 求最小化操作数, ∣S∣≤105 . 题解 显然应该多使用操作2 ...

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

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

  6. bzoj4044 [Cerc2014] Virus synthesis

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

  7. BZOJ4044: [Cerc2014] Virus synthesis(回文树+DP)

    Description Viruses are usually bad for your health. How about fighting them with... other viruses? ...

  8. [CERC2014] Virus synthesis

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

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

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

随机推荐

  1. Azure 部署K8S(二)

    在"China Azure中部署Kubernetes(K8S)集群"一文中,我们使用的ACS Version及Kubernete Version版本都比较低,ACS Version ...

  2. ubuntu14 安装tftp服务器

    安装 sudo apt-get install tftp-hpa tftpd-hpa 配置 sudo gedit /etc/default/tftpd-hpa 打开tftpd-hpa修改里面的配置: ...

  3. 可以修改类不用重启Tomcat加载整个项目

    修改类不重启Tomcat(不用手动重启) 修改tomcat  conf目录下的server.xml <Context path="/struts2" docBase=&quo ...

  4. HDU - 6096 处理后缀的字典树

    题意:给定n个字符串,m次询问,每次询问多少个字符串前缀是pre且后缀是suf,前后缀不可相交 字典树同时存储前后缀,假设字符串长为len则更新2*len个节点,依次按s[0],s[len-1],s[ ...

  5. 如何给oneindex网盘增加评论、密码查看、read me,头提示功能。

    来自我的博客:www.resource143.com 微信公众号:资源库resource 视频教程地址 点击查看 评论功能 特性 使用 GitHub 登录 支持多语言 [en, zh-CN, zh-T ...

  6. android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法

    MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views.错误 goo ...

  7. (转)OpenStack之服务端口号

    原文:https://blog.csdn.net/henulwj/article/details/47276391 在部署openstack的过程中,你会遇到配置各种服务的endpoint,opens ...

  8. lrzsz

    新搞的云服务器用SecureCRT不支持上传和下载,没有找到rz命令.记录一下如何安装rz/sz命令的方法. 一.工具说明 在SecureCRT这样的ssh登录软件里, 通过在Linux界面里输入rz ...

  9. 第2章—装配Bean—通过XML装配Bean

    通过XML装配Bean ​ 尽管我们在生成Bean的过程中可以用到很多方法,但我们依然需要Spring的XML配置来完善更多的需求,下面就来介绍下XML装配Bean的过程是怎样的. 3.1创建XML配 ...

  10. ubuntu手动安装PhantomJS

    1.切换到主目录:cd ~2.下载安装包:https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-Linux-x86_64.ta ...