1. 程式人生 > >bzoj4044 [Cerc2014] Virus synthesis

bzoj4044 [Cerc2014] Virus synthesis

efi tdi printf 圖片 print hide hid pos div

回文自動機上dp

f[x]表示形成x代表的回文串所需的最小步數,

若len[x]為奇數,f[x]=len[x],因為即使有更優的,也是直接添加,沒有復制操作,那樣就不用從x轉移了。

若len[x]為偶數,f[x]=min(f[fa[x]]+1,len[x]/2-len[fro[x]]+f[fro[x]]+1),因為fa[x]肯定是最後復制更優,那麽將復制前的子串末尾加一個字符即可,fro則是len不大於len[x]/2的最長的x的fail.

memsetT死了,改成每次只memset用的就過了

技術分享圖片
 1 #include<cstdio>
 2 #include<cstring>
 3
#include<algorithm> 4 #define N 100050 5 using namespace std; 6 int len[N],ch[N][5],nxt[N],fro[N],f[N]; 7 int T,n,ans,last,tot; 8 char s[N]; 9 inline void init(){ 10 ans=0x7fffffff; 11 last=0;tot=1; 12 memset(ch[0],0,sizeof ch[0]); 13 memset(ch[1],0,sizeof ch[1]); 14 nxt[0
]=nxt[1]=1; 15 len[1]=-1; 16 } 17 inline int getfail(int x,int en){ 18 while(s[en]!=s[en-len[x]-1])x=nxt[x]; 19 return x; 20 } 21 inline void insert(int t,int en){ 22 int now=getfail(last,en); 23 if(!ch[now][t]){ 24 int x=++tot; 25 memset(ch[x],0,sizeof ch[x]);
26 len[x]=len[now]+2; 27 int fa=getfail(nxt[now],en); 28 nxt[x]=ch[fa][t]; 29 fa=fro[now]; 30 if(len[x]<=2)fro[x]=0; 31 else{ 32 while(s[en]!=s[en-len[fa]-1]||(len[fa]+2)*2>len[x]) 33 fa=nxt[fa]; 34 fro[x]=ch[fa][t]; 35 } 36 if(len[x]&1||len[x]<=2)f[x]=len[x]; 37 else f[x]=min(f[now]+1,len[x]/2-len[fro[x]]+f[fro[x]]+1); 38 ans=min(ans,n-len[x]+f[x]); 39 ch[now][t]=x; 40 } 41 last=ch[now][t]; 42 } 43 int hash(char x){ 44 if(x==A)return 0; 45 if(x==T)return 1; 46 if(x==C)return 2; 47 return 3; 48 } 49 void work(){ 50 init(); 51 scanf("%s",s); 52 n=strlen(s); 53 for(int i=0;i<n;i++) 54 insert(hash(s[i]),i); 55 printf("%d\n",ans); 56 } 57 int main(){ 58 scanf("%d",&T); 59 while(T--)work(); 60 return 0; 61 }
View Code

bzoj4044 [Cerc2014] Virus synthesis