zoukankan      html  css  js  c++  java
  • Milk Patterns

    题目大意:给你一个数组,求这个数组里面至少重复k次的子串。
     
    分析:后缀数组的练手题目...不过给的数字比较大,可以先离散化处理一下即可。
     
    代码如下:
    ===============================================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 2e4+7;
    
    struct SuffixArr
    {
        int tempx[MAXN], tempy[MAXN], text[MAXN], Hash[MAXN];
        int rank[MAXN], sa[MAXN], sum[MAXN], height[MAXN];
        int *x, *y, N, MaxId;
    
        void GetText(int data[], int len)
        {
            N = len, x=tempx, y=tempy;
    
            for(int i=0; i<N; i++)
                Hash[i] = data[i];
    
            sort(Hash, Hash+N);
            MaxId = unique(Hash, Hash+N) - Hash;
    
            for(int i=0; i<N; i++)
            {
                text[i] = x[i] = lower_bound(Hash, Hash+MaxId, data[i])-Hash;
                y[i] = i;
            }
        }
        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;
    
          ///  debug(text);
          ///  debug(rank);
    
            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(height);
        }
        void debug(int p[])
        {
            for(int i=0; i<N; i++)
                printf("%d ", p[i]);
            printf("
    ");
        }
    };
    
    SuffixArr suf;
    int data[MAXN];
    
    bool Find(int times, int k)
    {
        int cnt=0;
    
        for(int i=0; i<suf.N; i++)
        {
            if(suf.height[i] < k)
                cnt = 0;
            else
            {
                cnt += 1;
                if(cnt == times-1)
                    return true;
            }
        }
    
        return false;
    }
    
    int main()
    {
        int N, times;
    
        while(scanf("%d%d", &N, &times) != EOF)
        {
            for(int i=0; i<N; i++)
                scanf("%d", &data[i]);
            data[N] = -1;
    
            suf.GetText(data, N+1);
            suf.GetSa();
            suf.GetHeight();
    
            int L=0, R=N, ans=0;
    
            while(L <= R)
            {
                int Mid = (L+R)>>1;
    
                if(Find(times, Mid) == true)
                {
                    ans = Mid;
                    L = Mid + 1;
                }
                else
                    R = Mid - 1;
            }
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    mysql 加入列,改动列,删除列。
    C语言中的static 具体分析
    [Python网络编程]gevent httpclient以及网页编码
    iOS学习之 plist文件的读写
    数据库设计中的14个技巧
    最简单的基于FFMPEG的封装格式转换器(无编解码)
    一次重要的爱情婚姻抉择,您怎么看?
    2014年到期的myeclipse5.5.1注冊码
    24点经典算法
    使用val()方法设置表单中的默认选中项
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4781713.html
Copyright © 2011-2022 走看看