dna

Posted VictBr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dna相关的知识,希望对你有一定的参考价值。

长度不超过一半的最长回文后缀还不太会求。。先mark

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 101000,A = 4,B = 5;


struct Node{
    int len,next[A],suf,fa;
    void clean(){
        memset(next,0,sizeof(next));
        suf = 0;len = 0;fa = 0;
    }
}nod[N];//1为长度为-1的root,2为长度为0的root 


char s[N];
map<int,int> q;
int T,n,maxsuf,len,base[N],f[N],g[N],ans,half[N],suf2[N];
void init();
int main(){
    scanf("%d",&T);
    base[0] = 1;for (int i = 1;i <= n;i++) base[i] = base[i-1]*B;
    while (T--){
        memset(suf2,0,sizeof(suf2));
        scanf("%s",s+1);n = strlen(s+1);
        for (int i = 1;i <= n;i++){
            if (s[i] == G) s[i] = B;
            if (s[i] == T) s[i] = D;
        }
        s[0] = &;
        init();
        ans = n;
        
        for (int i = 3;i <= len;i++){
            int u = nod[i].suf;
            while (nod[u].len*2 > nod[i].len) u = nod[u].suf;
            if (u < 2) u = 2;
            suf2[i] = u;
        }
        
        g[2] = 1;g[1] = n;
        for (int i = 3;i <= len;i++){
            if (nod[i].len & 1) g[i] = nod[i].len;    
            else{
                g[i] = min(g[nod[i].fa]+1,g[suf2[i]]+nod[i].len/2-nod[suf2[i]].len+1);
                if (q[half[i]] != 0) g[i] = min(g[i],q[half[i]]+1);
            }
        }
        for (int i = 3;i <= len;i++){
            ans = min(ans,g[i]+n-nod[i].len);
//            printf("%d %d %d %d %d\n",i,g[i],suf2[i],nod[i].len,nod[i].suf);
        }
        cout << ans << "\n";
        q.clear();        
    }
    return 0;
}
void init(){
    len = 0;
    nod[++len].clean();
    nod[1].len = -1;nod[1].suf = 1;
    nod[++len].clean();
    nod[2].len = 0;nod[2].suf = 1;
    suf2[1] = suf2[2] = 1;
    maxsuf = 2;
    for (int i = 1;i <= n;i++){
        int next;
//        cout << i << endl;
        while (s[i-nod[maxsuf].len-1] != s[i]){
//            if (maxsuf != 0) cout << maxsuf << endl;            
            maxsuf = nod[maxsuf].suf;
        }
//        cout << i << endl;
        Node &g = nod[maxsuf];
//        cout << maxsuf << endl;
        if (g.next[s[i]-A] == 0) {
            g.next[s[i]-A] = ++len;
            
            nod[len].clean();
            nod[len].fa = maxsuf;
            if (maxsuf == -1) f[len] = s[i]-A;
            else f[len] = f[len]*B+s[i]-A+(s[i]-A)*base[nod[maxsuf].len+1];
            if (nod[maxsuf].len%2 == 0) half[len] = half[maxsuf]*B+s[i]-A;
            nod[len].len = g.len+2;
        
            next = g.next[s[i]-A];
            maxsuf = nod[maxsuf].suf;
            while (s[i-nod[maxsuf].len-1] != s[i])
                maxsuf = nod[maxsuf].suf;
            nod[len].suf = nod[maxsuf].next[s[i]-A];
            if (nod[len].suf == len || nod[len].suf == 0) nod[len].suf = 2;        
            
            /*
            maxsuf = nod[len].suf;
            while (maxsuf > 1 && nod[maxsuf].len*2+4 > nod[len].len){
                maxsuf = nod[maxsuf].suf;
                while (s[i-nod[maxsuf].len-1] != s[i])
                    maxsuf = nod[maxsuf].suf;
            }
            if (maxsuf > 1) suf2[len] = nod[maxsuf].next[s[i]-‘A‘];
            else if (nod[len].len == 1) suf2[len] = 1;
            else suf2[len] = nod[1].next[s[i]-‘A‘];
            */
            maxsuf = next;        
        }
        else maxsuf = g.next[s[i]-A];
//        if (maxsuf == 0) cout << "A\n";
    }
     /*check
        for (int i = 1;i <= len;i++){
            Node &g = nod[i];
            printf("%d %d\n",g.len,g.suf);
            for (int j = 0;j < 4;j++)
                printf("%d ",g.next[j]);
            printf("\n");
        }
     */
}

 

以上是关于dna的主要内容,如果未能解决你的问题,请参考以下文章

POJ3691DNA repair(AC自动机,DP)

什么是DNA的弥散性复制?有全保留复制么?它们与半保留复制有什么区别

18.06.03 POJ 4126:DNA 15年程设期末05(状压DP)

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

用samtools的rmdup去除PCR重复reads

HDU3247 Resource Archiver(AC自动机+BFS+DP)