设f[i]为形成极长回文串i的最小操作数。答案为min f[i]+n-len[i]。

在不形成偶回文的情况下形成奇回文的最小操作数为该串长度。可以不考虑(但ans赋为len)。

正确性基于:

1)奇、偶回文嵌套形成最终的偶回文一定可以转化为由在不形成奇回文的情况下形成偶回文。

2)奇、偶回文嵌套形成最终的奇回文并不需要讨论。

也不知道理解对没有。。。

所以,以下的回文串皆代指偶回文。

转移1:f[i]=f[j]+1 | 在极长回文串j前后补上一对相同字符可得到i。

举例:

aabbaa : a aa aab aabbaa

caabbaac: a aa aab caab caabbaac

统一化:f[偶根]=1 => f["aa"]=2

转移2:f[i]=min f[j]+1+len[i]/2-len[j] | j=tmp[i].

举例:

abba : a ab abba

abbaccabba: abba abbac abbaccabba

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=3e5+10;
  4. map<char,int> tr={
  5. {'A',0},{'G',1},{'C',2},{'T',3}
  6. };
  7. struct pam_ {
  8. char *str;
  9. int last,size;
  10. int tmp[N],len[N],fail[N],ch[N][26];
  11. int getFail(int x,int n) {
  12. while(str[n]!=str[n-len[x]-1]) x=fail[x];
  13. return x;
  14. }
  15. void build(char *bStr) {
  16. str=bStr;
  17. str[0]=-1;
  18. len[1]=-1;
  19. fail[0]=1;
  20. last=0;
  21. size=1;
  22. memset(ch[0],0,sizeof ch[0]);
  23. memset(ch[1],0,sizeof ch[1]);
  24. for(int i=1; str[i]; ++i) {
  25. int c=tr[str[i]];
  26. int p=getFail(last,i);
  27. if(!ch[p][c]) {
  28. int q=++size;
  29. memset(ch[q],0,sizeof ch[q]);
  30. len[q]=len[p]+2;
  31. fail[q]=ch[getFail(fail[p],i)][c];
  32. ch[p][c]=q;
  33. if(len[q]<=2) tmp[q]=fail[q];
  34. else {
  35. int x=tmp[p];
  36. while(str[i]!=str[i-len[x]-1]||(len[x]+2)*2>len[q]) x=fail[x];
  37. tmp[q]=ch[x][c];
  38. }
  39. }
  40. last=ch[p][c];
  41. }
  42. }
  43. int calc() {
  44. static int que[N];
  45. static int f[N];
  46. int n,ans,hd,tl;
  47. n=ans=strlen(str+1);
  48. que[hd=0,tl=1]=0;
  49. for(int i=2; i<=size; ++i) {
  50. f[i]=len[i];
  51. }
  52. f[0]=1,f[1]=0;
  53. while(hd<tl) {
  54. int x=que[++hd];
  55. for(int i=0; i<4; ++i) {
  56. int y=ch[x][i];
  57. if(!y) continue;
  58. f[y]=f[x]+1;
  59. que[++tl]=y;
  60. f[y]=min(f[y],f[tmp[y]]+1+len[y]/2-len[tmp[y]]);
  61. ans=min(ans,f[y]+n-len[y]);
  62. }
  63. }
  64. return ans;
  65. }
  66. } pam;
  67. int main() {
  68. int T;
  69. scanf("%d",&T);
  70. static char str[N];
  71. while(T--) {
  72. scanf("%s",str+1);
  73. pam.build(str);
  74. // puts("built");
  75. printf("%d\n",pam.calc());
  76. }
  77. return 0;
  78. }

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

  1. luogu_4762: [CERC2014]Virus synthesis

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

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

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

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

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

  4. bzoj4044 [Cerc2014] Virus synthesis

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

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

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

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

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

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

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

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

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

  9. P4762 [CERC2014]Virus synthesis

    题意 真是道回文自动机好题. 首先考虑答案必定是一个回文串+剩余部分的形式,因此可以建出回文自动机,之后考虑每个长度为偶数的回文串. 对于一个长度为偶数的回文串,设它在回文自动机上对应的节点为\(x\ ...

随机推荐

  1. C#下载Url文件到本地

    protected void Page_Load(object sender, EventArgs e) { string filePath = Request.Params["FilePa ...

  2. sqlserver 并行度

    转载地址:http://www.cnblogs.com/zhijianliutang/p/4148540.html

  3. logstash报错 :backtrace=>["org/jruby/RubyIO.java:1457:in `write'", "org/jruby/RubyIO.java:1428:in `write'"

    报错: [2019-04-16T15:54:07,827][FATAL][logstash.runner ] An unexpected error occurred! {:error=>#&l ...

  4. iBtais 多重嵌套循环

    iBatis支持集合循环, 但是如何做到双重循环, 请见下例子 例子描述: 需要去三张结构相同的表中获取信息, 需要将信息拼合去重后返回 入参数据类型: Map<String,Object> ...

  5. cobbler实现系统自动化安装centos

    cobbler [epel] cobbler服务集成 PXE DHCP rsync Http DNS Kickstart IPMI[电源管理] 1.软件安装 yum install cobbler d ...

  6. android-读取MediaProvider

    1.MediaProvider存储手机中的媒体文件,用 SQLite 数据库存储图片.视频.音频等多媒体文件的信息,供视频播放器.音乐播放器.图库使用.以 root 权限进入 adb shell,使用 ...

  7. IDEA教程

    IDE-Intellij IDEA 之前同事一直给我推荐IDEA,说跟eclipse相比就是石器时代的工具,我一直任何一个工具熟练起来都很牛逼,所以一直坚持使用eclipse,不过看了下IDEA的功能 ...

  8. OC中NSString的使用、字符串的使用

    字符串作为OC语言的基本对象类型,被我们在各种地方广泛使用,因此熟悉掌握字符串的属性和方法,是OC必不可少的基础之一. 字符串分为可变字符串(NSMutableString)和不可变字符串(NSStr ...

  9. git忽视修改的文件

    对于tracked文件来说,使用.gitignore是不行的.但是git提供了新的方法. 使用命令 git update-index --assume-unchanged <files>, ...

  10. FPGA学习之旅

    从大学就开始使用stm32,工作之后,仍然没有摆脱,从f1系列,到f4系列,然后又到L1系列,尽管可以满足工作需要,但还是希望可以摆脱束缚,尝试学习FPGA,希望能够遇到一个好机遇.