zoukankan      html  css  js  c++  java
  • 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("
    ");
            }
         */
    }
  • 相关阅读:
    对PostgreSQL的 seq scan , bitmap index scan 和 index scan 的进一步理解
    C# IEnumerable和IEnumerator的区别,如何实现
    老板运煤问题及解决方案
    快速排序和简单排序
    给定数组,查找最小的k个元素或最大的k个元素
    一列数字的规则如下;1,1,2,3,5,8,13,21,34........ 求第30位数字是多少,用递规和非递归两种方法算法实现
    C# 如何利用反射来加载程序集,并调用程序集中有关类的方法
    http 请求 header 应用分析
    templatemonster 10231 面朝大海 你听到什么?
    足球俱乐部 网站模板 附带源文件 字体
  • 原文地址:https://www.cnblogs.com/victbr/p/6520561.html
Copyright © 2011-2022 走看看