zoukankan      html  css  js  c++  java
  • Palindrome

    题目大意:RT
     
    分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的。
     
    线段数+后缀数组代码如下:
    ===========================================================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 1e4+7;
    
    struct SuffixArr
    {
        int tempx[MAXN], tempy[MAXN], text[MAXN];
        int rank[MAXN], sa[MAXN], height[MAXN], sum[MAXN];
        int *x, *y, N, MaxId;
    
        void GetText(char s[])
        {
            N = strlen(s)*2+2, MaxId = 200;
            x = tempx, y = tempy;
            int i;
            for(i=0; s[i]; i++)
            {
                text[i] = text[N-i-2] = x[i] = x[N-i-2] = (int)s[i];
                y[i] = i, y[N-i-2] = N-i-2;
            }
    
            text[i] = x[i] = 1, y[i] = i;
            text[N-1] = x[N-1] = 0, y[N-1] = N-1;
    
           /// debug();
        }
        bool cmp(int i, int len)
        {
            if(sa[i]+len > N || sa[i-1]+len > N)
                return false;
            if(y[sa[i]] != y[sa[i-1]] || y[sa[i]+len] != y[sa[i-1]+len])
                return false;
    
            return true;
        }
        void baseSort()
        {
            for(int i=0; i<MaxId; i++)
                sum[i] = 0;
            for(int i=0; i<N; i++)
                sum[ x[ y[i] ] ] += 1;
            for(int i=1; i<MaxId; i++)
                sum[i] += sum[i-1];
            for(int i=N-1; i>=0; i--)
                sa[ --sum[ x[ y[i] ] ] ] = y[i];
        }
        void GetSa()
        {
            baseSort();
    
            for(int len=1; len<=N; len<<=1)
            {
                int id = 0;
    
                for(int i=N-len; i<N; i++)
                    y[id++] = i;
                for(int i=0; i<N; i++)if(sa[i] >= len)
                    y[id++] = sa[i] - len;
    
                baseSort();
                swap(x, y);
                x[ sa[0] ] = id = 0;
    
                for(int i=1; i<N; i++)
                {
                    if(cmp(i, len) == true)
                        x[ sa[i] ] = id;
                    else
                        x[ sa[i] ] = ++id;
                }
    
                MaxId = id + 1;
    
                if(MaxId >= N)break;
            }
        }
        void GetHeight()
        {
            for(int i=0; i<N; i++)
                rank[ sa[i] ] = i;
    
    
            for(int k=0, i=0; i<N; i++)
            {
                if(!rank[i])
                {
                    height[0] = k = 0;
                    continue;
                }
                if(k)k--;
    
                int pre = sa[ rank[i]-1 ];
    
                while(text[i+k] == text[pre+k])
                    k++;
                height[rank[i]] = k;
            }
           /// debug();
        }
    
        void debug()
        {
            for(int i=0; i<N; i++)
                printf("%d: %d
    ", i, height[i]);
        }
    };
    struct segmentTree
    {
        int val[MAXN], L[MAXN], R[MAXN];
    
        void Build(int root, int l, int r, int p[])
        {
            L[root] = l, R[root] = r;
    
            if(l == r)
            {
                val[root] = p[l];
                return ;
            }
    
            int Mid = (l+r)>>1;
    
            Build(root<<1, l, Mid, p);
            Build(root<<1|1, Mid+1, r, p);
    
            val[root] = min(val[root<<1], val[root<<1|1]);
        }
        int  Query(int root, int u, int v)
        {
    
            if(L[root] == u && R[root] == v)
                return val[root];
    
            int Mid = (L[root]+R[root]) / 2;
    
            if(v <= Mid)
                return Query(root<<1, u, v);
            else if(u > Mid)
                return Query(root<<1|1, u, v);
            else
                return min(Query(root<<1, u, Mid), Query(root<<1|1, Mid+1, v));
        }
    };
    
    SuffixArr suf;
    segmentTree seg;
    char s[MAXN];
    
    int main()
    {
        while(scanf("%s", s) != EOF)
        {
            int len = strlen(s)+1;
    
            suf.GetText(s);
            suf.GetSa();
            suf.GetHeight();
    
            seg.Build(1, 0, suf.N-1, suf.height);
    
            int MaxLen=1, k=0, x, y;
    
            for(int i=0; i<len-1; i++)
            for(int j=0; j<2; j++)
            {
                if(j==0)
                    x = suf.rank[len*2-i-2];
                else
                    x = suf.rank[len*2-i-1];
    
                if(i==0 && j)continue;
    
                y = suf.rank[i+1];
    
                if(x > y)swap(x, y);
    
                int m = seg.Query(1, x+1, y) * 2 + j;
    
                if(MaxLen < m)
                {
                    MaxLen = m;
                    k = i-(m+j)/2+1;
                }
            }
    
            s[k+MaxLen] = 0;
    
            printf("%s
    ", s+k);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    【转】CRC校验
    【转】MapReduce程序的工作过程
    【转】hadoop机架感知
    【转】git常用命令
    Code Examples for scala actor link
    【转】ThreadLocal原理及其实际应用
    【转】scala解惑: 偏函数与部分应用函数
    (九)Maven坐标详解
    (八)Eclipse创建Maven项目运行mvn命令
    (七)Maven使用的最佳实践
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4782866.html
Copyright © 2011-2022 走看看