zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java实现分页
    研发技能列表
    shell 函数
    养生
    再谈创新
    写代码注意事项
    排查问题方法
    简历撰写
    jenkins
    架构
  • 原文地址:https://www.cnblogs.com/lokiii/p/10014574.html
Copyright © 2011-2022 走看看