• POJ 3261 可重叠k次最长重复子串


    Milk Patterns
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 13127   Accepted: 5842
    Case Time Limit: 2000MS

    Description

    Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular patterns in the daily milk quality.

    To perform a rigorous study, he has invented a complex classification scheme by which each milk sample is recorded as an integer between 0 and 1,000,000 inclusive, and has recorded data from a single cow over N (1 ≤ N ≤ 20,000) days. He wishes to find the longest pattern of samples which repeats identically at least K (2 ≤ K ≤ N) times. This may include overlapping patterns -- 1 2 3 2 3 2 3 1 repeats 2 3 2 3 twice, for example.

    Help Farmer John by finding the longest repeating subsequence in the sequence of samples. It is guaranteed that at least one subsequence is repeated at least K times.

    Input

    Line 1: Two space-separated integers: N and K 
    Lines 2..N+1: N integers, one per line, the quality of the milk on day i appears on the ith line.

    Output

    Line 1: One integer, the length of the longest pattern which occurs at least K times
    /*
    POJ 3261 可重叠k次最长重复子串
    
    给你一串数字,求其中出现k次的最长子串
    
    最开始想的是二分最长长度,然后判断一下是否有k个子串
    但是在判断的时候2b了,并没有判断它们是否是同一个子串,于是乎
    应该进行分组讨论,因为是height中存的是排过序后的最长前缀
    假设height[] = 0 0 1 4 4 4 3 2 4 4
    只有前3个4是同一个子串(排序后一段连续子串是相似的)
    
    所以成了找出height连续大于等于mid的长度sum,判断sum+1是否>=k
    
    hhh-2016-03-11 21:29:00
    */
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <iostream>
    #include <cstring>
    #include <map>
    #include <cstdio>
    #include <vector>
    #include <functional>
    #define lson (i<<1)
    #define rson ((i<<1)|1)
    using namespace std;
    typedef long long ll;
    const int maxn = 100050;
    
    int t1[maxn],t2[maxn],c[maxn];
    bool cmp(int *r,int a,int b,int l)
    {
        return r[a]==r[b] &&r[l+a] == r[l+b];
    }
    
    void get_sa(int str[],int sa[],int Rank[],int height[],int n,int m)
    {
        n++;
        int p,*x=t1,*y=t2;
        for(int i = 0; i < m; i++) c[i] = 0;
        for(int i = 0; i < n; i++) c[x[i] = str[i]]++;
        for(int i = 1; i < m; i++) c[i] += c[i-1];
        for(int i = n-1; i>=0; i--) sa[--c[x[i]]] = i;
        for(int j = 1; j <= n; j <<= 1)
        {
            p = 0;
            for(int i = n-j; i < n; i++) y[p++] = i;
            for(int i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j;
            for(int i = 0; i < m; i++) c[i] = 0;
            for(int i = 0; i < n; i++) c[x[y[i]]]++ ;
            for(int i = 1; i < m; i++) c[i] += c[i-1];
            for(int i = n-1; i >= 0; i--)  sa[--c[x[y[i]]]] = y[i];
    
            swap(x,y);
            p = 1;
            x[sa[0]] = 0;
            for(int i = 1; i < n; i++)
                x[sa[i]] = cmp(y,sa[i-1],sa[i],j)? p-1:p++;
            if(p >= n) break;
            m = p;
        }
        int k = 0;
        n--;
        for(int i = 0; i <= n; i++)
            Rank[sa[i]] = i;
        for(int i = 0; i < n; i++)
        {
            if(k) k--;
            int j = sa[Rank[i]-1];
            while(str[i+k] == str[j+k]) k++;
            height[Rank[i]] = k;
        }
    }
    
    int Rank[maxn],height[maxn];
    int sa[maxn],str[maxn];
    int a[maxn];
    int n;
    
    bool judge(int ans,int k)
    {
        int i =2;
        while(1)
        {
            while(height[i] < ans && i <= n) i++;
            int num = 0;
            if(i > n) break;
            while(height[i] >= ans && i <= n){num++;i++;}
            if(num+1 >= k)return 1;
        }
        return 0;
    }
    map<int,int> mp;
    int main()
    {
        int k,cas = 1;
        while(scanf("%d%d",&n,&k) != EOF)
        {
            int tot = 1,x;
            mp.clear();
            for(int i  = 0; i < n; i++)
            {
                scanf("%d",&x);
                if(!mp[x])
                    mp[x] = tot++;
                a[i] = mp[x];
            }
            a[n] = 0;
    
            get_sa(a,sa,Rank,height,n,n+1);
            int ans = 0;
            int l=1,r=n;
    //        for(int i =2;i <= n;i++)
    //            printf("%d %d
    ",sa[i],height[i]);
    //        cout <<endl;
            while(l <= r)
            {
                int mid = (l+r)>>1;
                if(judge(mid,k))
                {
                    ans = mid;
                    l = mid + 1;
                }
                else
                    r = mid-1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

    
    
  • 相关阅读:
    MVC ActionResult JsonResult
    xml文件
    使用socket实现聊天功能
    使用多线程完成Socket
    Socket编程
    U1总结
    多线程
    IO
    单例模式
    日期
  • 原文地址:https://www.cnblogs.com/Przz/p/5409579.html
Copyright © 2020-2023  润新知