zoukankan      html  css  js  c++  java
  • POJ 3693 Maximum repetition substring(最多重复次数的子串)

    Maximum repetition substring
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 10461   Accepted: 3234

    Description

    The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same consecutive substrings. For example, the repetition number of "ababab" is 3 and "ababa" is 1.

    Given a string containing lowercase letters, you are to find a substring of it with maximum repetition number.

    Input

    The input consists of multiple test cases. Each test case contains exactly one line, which
    gives a non-empty string consisting of lowercase letters. The length of the string will not be greater than 100,000.

    The last test case is followed by a line containing a '#'.

    Output

    For each test case, print a line containing the test case number( beginning with 1) followed by the substring of maximum repetition number. If there are multiple substrings of maximum repetition number, print the lexicographically smallest one.

    Sample Input

    ccabababc
    daabbccaa
    #

    Sample Output

    Case 1: ababab
    Case 2: aa

    题目链接:POJ 3693

    把所有可能构成的最多重复次数的子串所对应的循环节大小存下来,然后枚举$SA[i]$与循环节大小,如果刚好枚举到了这个$SA[i]$对应的就是这个循环节大小,那么就是最小的字典序解了,因为$SA[]$是按照字典序排的,当然要注意单个字符这种字符串,因此一开始要把长度定为1。

    另外这题数据非常弱,实际上枚举的时候需要加一些边界防止越界问题。可以试一下这些数据:

    kabhvlkba
    slgnaebbga
    lajnbabab
    kabkbakbvkab
    akbakabka
    akjbakjbajkba
    akjbakbaiajklbna
    kljdfnbisn
    akbvkab

    答案应该是

    a

    b

    abab

    a

    a

    akjbakjb

    a

    b

    a

    代码:

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <bitset>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define fin(name) freopen(name,"r",stdin)
    #define fout(name) freopen(name,"w",stdout)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 100010;
    int wa[N], wb[N], cnt[N], sa[N];
    int ran[N], height[N];
    char s[N];
    int pos[N];
    
    inline int cmp(int r[], int a, int b, int d)
    {
        return r[a] == r[b] && r[a + d] == r[b + d];
    }
    void DA(int n, int m)
    {
        int i;
        int *x = wa, *y = wb;
        for (i = 0; i < m; ++i)
            cnt[i] = 0;
        for (i = 0; i < n; ++i)
            ++cnt[x[i] = s[i]];
        for (i = 1; i < m; ++i)
            cnt[i] += cnt[i - 1];
        for (i = n - 1; i >= 0; --i)
            sa[--cnt[x[i]]] = i;
        for (int k = 1; k <= n; k <<= 1)
        {
            int p = 0;
            for (i = n - k; i < n; ++i)
                y[p++] = i;
            for (i = 0; i < n; ++i)
                if (sa[i] >= k)
                    y[p++] = sa[i] - k;
            for (i = 0; i < m; ++i)
                cnt[i] = 0;
            for (i = 0; i < n; ++i)
                ++cnt[x[y[i]]];
            for (i = 1; i < m; ++i)
                cnt[i] += cnt[i - 1];
            for (i = n - 1; i >= 0; --i)
                sa[--cnt[x[y[i]]]] = y[i];
            swap(x, y);
            x[sa[0]] = 0;
            p = 1;
            for (i = 1; i < n; ++i)
                x[sa[i]] = cmp(y, sa[i - 1], sa[i], k) ? p - 1 : p++;
            m = p;
            if (m >= n)
                break;
        }
    }
    void gethgt(int n)
    {
        int i, k = 0;
        for (i = 1; i <= n; ++i)
            ran[sa[i]] = i;
        for (i = 0; i < n; ++i)
        {
            if (k)
                --k;
            int j = sa[ran[i] - 1];
            while (s[j + k] == s[i + k])
                ++k;
            height[ran[i]] = k;
        }
    }
    namespace SG
    {
        int dp[N][17];
        void init(int l, int r)
        {
            int i, j;
            for (i = l; i <= r; ++i)
                dp[i][0] = height[i];
            for (j = 1; l + (1 << j) - 1 <= r; ++j)
            {
                for (i = l; i + (1 << j) - 1 <= r; ++i)
                    dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
            }
        }
        int ask(int l, int r)
        {
            int len = r - l + 1;
            int k = 0;
            while (1 << (k + 1) <= len)
                ++k;
            return min(dp[l][k], dp[r - (1 << k) + 1][k]);
        }
        int LCP(int l, int r, int len)
        {
            l = ran[l], r = ran[r];
            if (l > r)
                swap(l, r);
            if (l == r)
                return len - sa[l];
            return ask(l + 1, r);
        }
    }
    int main(void)
    {
        int T = 0, len, i, j;
        while (~scanf("%s", s) && s[0] != '#')
        {
            len = strlen(s);
            DA(len + 1, 130);
            gethgt(len);
            SG::init(1, len);
            int ans = 1;
            int sz = 0;
            for (int L = 1; L < len; ++L)
            {
                for (i = 0; i + L < len; i += L)
                {
                    int lcp = SG::LCP(i, i + L, len);
                    int cnt = lcp / L + 1;
                    int j = i - (L - lcp % L);
                    if (j >= 0 && lcp % L != 0 && SG::LCP(j , j + L, len) / L + 1 > cnt)
                        ++cnt;
                    if (cnt > ans)
                    {
                        ans = cnt;
                        sz = 0;
                        pos[sz++] = L;
                    }
                    else if (cnt == ans)
                        pos[sz++] = L;
                }
            }
            int length = 1;
            int st = 0;
            int flag = 0;
            for (i = 1; i <= len && !flag; ++i)
            {
                for (j = 0; j < sz; ++j)
                {
                    int unit = pos[j];
                    if (sa[i] + unit < len && SG::LCP(sa[i], sa[i] + unit, len) >= (ans - 1) * unit)
                    {
                        length = ans * unit;
                        st = sa[i];
                        flag = 1;
                        break;
                    }
                }
            }
            printf("Case %d: ", ++T);
            for (i = st; i < st + length; ++i)
                putchar(s[i]);
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    sudo 之后 unable to resolve host的问题解决办法
    Linux 查找具体的文件名称
    linux 访问远程务器代码
    spark 安装配置
    R基本介绍
    BIEE多层表头报表的制作方法
    支付宝新漏洞引发恐慌,那如何关闭小额免密支付呢
    大家注意了,支付宝被曝重大安全漏洞,回应称正在跟进排查
    2017年5个不应该被忽视的机器学习项目
    婚前最后一次加班
  • 原文地址:https://www.cnblogs.com/Blackops/p/7520818.html
Copyright © 2011-2022 走看看