• [BZOJ1717][Usaco2006 Dec]Milk Patterns 产奶的模式


    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

    Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1297  Solved: 705 [Submit][Status][Discuss]

    Description

    农夫John发现他的奶牛产奶的质量一直在变动。经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠。我们称之为一个“模式”。 John的牛奶按质量可以被赋予一个0到1000000之间的数。并且John记录了N(1<=N<=20000)天的牛奶质量值。他想知道最长的出现了至少K(2<=K<=N)次的模式的长度。比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次。当K=2时,这个长度为4。

    Input

    * Line 1: 两个整数 N,K。

    * Lines 2..N+1: 每行一个整数表示当天的质量值。

    Output

    * Line 1: 一个整数:N天中最长的出现了至少K次的模式的长度

    Sample Input

    8 2
    1
    2
    3
    2
    3
    2
    3
    1

    Sample Output

    4
    求出后缀数组以及height数组,二分答案,如果有连续$k-1$个的height>=mid则可行
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int maxn = 20000 + 10;
    int n, m, k, s[maxn];
    int *p[maxn], cnt, last;
    class cmp1{
        public:
            bool operator () (int *a, int *b){
                return *a < *b;
            }
    };
    int tax[maxn], tp[maxn], sa[maxn], rank[maxn], height[maxn];
    inline bool cmp(int *r, int x, int y, int l){
        return r[x] == r[y] && r[x + l] == r[y + l];
    }
    inline void rsort(){
        for(int i = 0; i <= m; i++) tax[i] = 0;
        for(int i = 1; i <= n; i++) tax[rank[tp[i]]]++;
        for(int i = 1; i <= m; i++) tax[i] += tax[i - 1];
        for(int i = n; i; i--) sa[tax[rank[tp[i]]]--] = tp[i];
    }
    void suffix(){
        for(int i = 1; i <= n; i++){
            rank[i] = s[i];
            tp[i] = i;
        }
        m = n;
        rsort();
        for(int p, w = 1; w < n; w <<= 1, m = p){
            p = 0;
            for(int i = n - w + 1; i <= n; i++) tp[++p] = i;
            for(int i = 1; i <= n; i++) if(sa[i] > w) tp[++p] = sa[i] - w;
            rsort();
            swap(rank, tp);
            p = rank[sa[1]] = 1;
            for(int i = 2; i <= n; i++)
                rank[sa[i]] = cmp(tp, sa[i - 1], sa[i], w) ? p : ++p; 
        }
        for(int i = 1, j, k = 0; i <= n; height[rank[i++]] = k)
            for(k ? k-- : 0, j = sa[rank[i] - 1]; s[i + k] == s[j + k]; k++);
    }
    inline bool Judge(int mid){
        int tot = 0;
        for(int i = 1; i <= n; i++)
            if(height[i] >= mid){
                tot++;
                if(tot == k - 1) return true;
            }
            else tot = 0;
        return false;
    }
    int main(){
        scanf("%d %d", &n, &k);
        for(int i = 1; i <= n; i++)    scanf("%d", p[i] = s + i);
        sort(p + 1, p + n + 1, cmp1());
        last = *p[1];
        *p[1] = cnt = 1;
        for(int i = 2; i <= n; i++){
            if(*p[i] != last) cnt++;
            last = *p[i];
            *p[i] = cnt;
        }
        suffix();
        int l = 1, r = n, mid, ans;
        while(l <= r){
            mid = l + r >> 1;
            if(Judge(mid)){
                ans = mid;
                l = mid + 1;
            }
            else r = mid - 1;
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    GregorianCalendar
    IfcDataOriginEnum
    Element
    IfcRecurrenceTypeEnum
    IfcDocumentInformation
    IfcTimeStamp
    IfcLibrarySelect
    IfcTimeOrRatioSelect
    Document
    IfcLanguageId
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7482118.html
Copyright © 2020-2023  润新知