码迷,mamicode.com
首页 > 其他好文 > 详细

dna

时间:2017-03-08 18:47:49      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:std   out   clu   node   clean   scanf   char   main   har   

长度不超过一半的最长回文后缀还不太会求。。先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

标签:std   out   clu   node   clean   scanf   char   main   har   

原文地址:http://www.cnblogs.com/victbr/p/6520561.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!