• 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;
    }
  • 相关阅读:
    win7下php7.1运行getenv('REMOTE_ADDR')fastcgi停止运行
    Laravel 单设备登录
    CGI与FastCGI
    一起谈.NET技术,c#数据库存取图片的三种方式 狼人:
    一起谈.NET技术,ASP.NET的状态管理 狼人:
    一起谈.NET技术,Visual Studio 2010层架构验证的实现 狼人:
    一起谈.NET技术,4.0中的并行计算和多线程详解(二) 狼人:
    一起谈.NET技术,利用Visual Studio 2010流程模板实现Scrum敏捷开发 狼人:
    一起谈.NET技术,ASP.NET 安全漏洞临时解决方案 狼人:
    一起谈.NET技术,初识Silverlight 4及其架构 狼人:
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10491517.html
Copyright © 2020-2023  润新知