• 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("
    ");
            }
         */
    }
  • 相关阅读:
    今天发现之前瑞乐做的登录和注册居然都是用的get请求,瞬间出了一身冷汗.
    用grunt进行前端工程化之路
    移动端开发库zepto 之我思
    构造高度自适应的textarea
    maxlength属性在textarea里奇怪的表现
    在windows下使用linux的开发环境
    移动web开发的一些坑
    [译]开始学习webpack
    完美解决移动Web小于12px文字居中的问题
    再谈移动端Web屏幕适配
  • 原文地址:https://www.cnblogs.com/victbr/p/6520561.html
Copyright © 2020-2023  润新知