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
",i,g[i],suf2[i],nod[i].len,nod[i].suf);
        }
        cout << ans << "
";
        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
";
    }
     /*check
        for (int i = 1;i <= len;i++){
            Node &g = nod[i];
            printf("%d %d
",g.len,g.suf);
            for (int j = 0;j < 4;j++)
                printf("%d ",g.next[j]);
            printf("
");
        }
     */
}
原文地址:https://www.cnblogs.com/victbr/p/6520561.html