zoukankan      html  css  js  c++  java
  • bzoj4044: [Cerc2014] Virus synthesis

    做题要冷静啊。。

    仔细分析一下题面会发现这样造串的方式,对于任意一个串一定是前面一堆+一个偶回文+后面一堆

    答案就是把某一个回文造出来的代价+n-这个回文的长度

    还有就是翻转永远不会劣于加字符

    那么把回文自动机造出来,把每个回文的最小步数搞出来就好了

    假如是奇回文,直接f[pre]+2

    偶的话分成两种情况,由pre转移过来和不由pre转移

    对于偶回文,最后一步一定是翻转,那么从pre转移过来就是f[pre]+1,因为可以在pre翻转之前先加一个字符

    反之,就必须利用当前回文的最后一个字符,也就是把当前回文的一半搞出来

    倍增跳fail找到第一个len*2<= now len 的点,用它翻转再补满一半再翻转一次,就是f[u]+nowlen/2-len+1

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int _=1e2;
    const int maxn=1*1e5+_;
    const int maxc=4+3;
    const int mbit=17+3;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void write(int x)
    {
        if(x>=10)write(x/10);
        putchar(x%10+'0');
    }
    
    int n,a[maxn];char ss[maxn];
    void zxcv(int i)
    {
             if(ss[i]=='A')a[i]=1;
        else if(ss[i]=='C')a[i]=2;
        else if(ss[i]=='G')a[i]=3;
        else a[i]=4;
    }
    
    struct Pnode
    {
        int w[maxc],len,dep,fail[mbit];
        void clear()
        {
            len=0;dep=0;
            memset(w,0,sizeof(w));
            memset(fail,0,sizeof(fail));
        }
    };//fail树中的深度,倍增找祖先 
    struct PAM
    {
        Pnode ch[maxn];int cnt,last;
        void init()
        {
            cnt=1;last=1; ch[0].clear(),ch[1].clear();
            ch[0].len=0,ch[1].len=-1;
            ch[0].fail[0]=1;
            ch[0].dep=1;
        }
        int f[maxn];
        void insert(int k,int x)
        {
            int pre=last;
            while(a[k]!=a[k-1-ch[pre].len])
            pre=ch[pre].fail[0];
            if(ch[pre].w[x]==0)
            {
                int now=++cnt; ch[now].clear();
                ch[now].len=ch[pre].len+2;
                ch[now].dep=ch[pre].dep+1; 
                
                int ppre=ch[pre].fail[0];
                while(a[k]!=a[k-1-ch[ppre].len])ppre=ch[ppre].fail[0];
                ch[now].fail[0]=ch[ppre].w[x];
                for(int i=1;(1<<i)<=ch[now].dep;i++)
                    ch[now].fail[i]=ch[ch[now].fail[i-1]].fail[i-1];
                
                ch[pre].w[x]=now;
                
                //.........update.............
                
                if(ch[now].len==1)f[now]=1;
                else if(ch[now].len==2)f[now]=2;
                else if(ch[now].len%2==1)f[now]=f[pre]+2;
                else
                {
                    f[now]=f[pre]+1;
                    int u=now,b=0;
                    while(1)
                    {
                        while(b>=0&&((1<<b)>ch[u].dep||ch[ch[u].fail[b]].len*2<=ch[now].len))b--;
                        if(b<0)break;
                        u=ch[u].fail[b];
                        b++;
                    }
                    u=ch[u].fail[0];
                    if(u!=0&&u!=1)
                        f[now]=min(f[now],f[u]+ch[now].len/2-ch[u].len+1);
                }
                
                //..........getf..............
            }
            last=ch[pre].w[x];
        }
    }P;
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int T;
        T=read();
        while(T--)
        {
            scanf("%s",ss+1);n=strlen(ss+1);
            P.init();
            for(int i=1;i<=n;i++)
            {
                if(i==21)
                {
                    int t;t++;
                }
                zxcv(i),P.insert(i,a[i]);
            }
            
            int ans=(1<<30);
            for(int i=2;i<=P.cnt;i++)
            {
                ans=min(ans,P.f[i]+n-P.ch[i].len);
            }
            write(ans);puts("");
        }
        
        return 0;
    }
  • 相关阅读:
    【Spring】9、Spring中的事件Event
    【Spring】8、Spring框架中的单例Beans是线程安全的么
    【Spring】7、拦截器HandlerInterceptor
    【Spring】5、利用自定义注解在SpringMVC中实现自定义权限检查
    【Spring】4、Spring中 @Autowired标签与 @Resource标签 的区别
    【Dubbo&&Zookeeper】2、 windows平台dubbo-admin管理平台搭建
    【Dubbo&&Zookeeper】4、 Java实现Dubbo服务提供者及消费者注册
    【Dubbo&&Zookeeper】3、Failed to read schema document 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd'问题解决方法
    【Dubbo&&Zookeeper】1、Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
    【Spring】3、BeanFactory 和 ApplicationContext的区别
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10491517.html
Copyright © 2011-2022 走看看