POJ 3693 Maximum repetition substring(后缀数组求最长重复子串)

来源:互联网 发布:吃鸡好玩在哪 知乎 编辑:程序博客网 时间:2024/04/29 18:20

题目大意:和spoj687类似,就是当长度相同是需要输出一个最小的字典序的序列。

解体思路:这次需要枚举所有的从i到d = i-L/i (d = i-L%i)的位置,然后记录保证最大值的同时,求出来字典序最小的。

Maximum repetition substring
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 7418 Accepted: 2217

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

ccabababcdaabbccaa#

Sample Output

Case 1: abababCase 2: aa
#include <algorithm>#include <iostream>#include <stdlib.h>#include <string.h>#include <iomanip>#include <stdio.h>#include <string>#include <queue>#include <cmath>#include <stack>#include <ctime>#include <map>#include <set>#define eps 1e-9///#define M 1000100///#define LL __int64#define LL long long///#define INF 0x7ffffff#define INF 0x3f3f3f3f#define PI 3.1415926535898#define zero(x) ((fabs(x)<eps)?0:x)#define mod 1000000007#define Read() freopen("autocomplete.in","r",stdin)#define Write() freopen("autocomplete.out","w",stdout)#define Cin() ios::sync_with_stdio(false)using namespace std;inline int read(){    char ch;    bool flag = false;    int a = 0;    while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));    if(ch != '-')    {        a *= 10;        a += ch - '0';    }    else    {        flag = true;    }    while(((ch = getchar()) >= '0') && (ch <= '9'))    {        a *= 10;        a += ch - '0';    }    if(flag)    {        a = -a;    }    return a;}void write(int a){    if(a < 0)    {        putchar('-');        a = -a;    }    if(a >= 10)    {        write(a / 10);    }    putchar(a % 10 + '0');}const int maxn = 100050;int wa[maxn], wb[maxn], wv[maxn], ws1[maxn];int sa[maxn];int cmp(int *r, int a, int b, int l){    return r[a] == r[b] && r[a+l] == r[b+l];}void da(int *r, int *sa, int n, int m){    int i, j, p, *x = wa, *y = wb;    for(i = 0; i < m; i++) ws1[i] = 0;    for(i = 0; i < n; i++) ws1[x[i] = r[i]]++;    for(i = 1; i < m; i++) ws1[i] += ws1[i-1];    for(i = n-1; i >= 0; i--) sa[--ws1[x[i]]] = i;    for(j = 1, p = 1; p < n; j <<= 1, m = p)    {        for(p = 0, i = n-j; i < n; i++) y[p++] = i;        for(i = 0; i < n; i++)            if(sa[i] >= j) y[p++] = sa[i]-j;        for(i = 0; i < n; i++) wv[i] = x[y[i]];        for(i = 0; i < m; i++) ws1[i] = 0;        for(i = 0; i < n; i++) ws1[wv[i]]++;        for(i = 1; i < m; i++) ws1[i] += ws1[i-1];        for(i = n-1; i >= 0; i--) sa[--ws1[wv[i]]] = y[i];        for(swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; i++)            x[sa[i]] = cmp(y, sa[i-1], sa[i], j)?p-1:p++;    }}int rank[maxn], height[maxn];void calheight(int *r, int *sa, int n){    int i, j, k = 0;    for(i = 1; i <= n; i++) rank[sa[i]] = i;    for(int i = 0; i < n; height[rank[i++]] = k)        for(k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);    return ;}int dp[maxn][30];void RMQ(int len){    for(int i = 1; i <= len; i++)        dp[i][0] = height[i];    for(int j = 1; 1<<j <= maxn; j++)    {        for(int i = 1; i+(1<<j)-1 <= len; i++)            dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);    }}int lg[maxn];int querry(int l, int r){    int k = lg[r-l+1];    return min(dp[l][k], dp[r-(1<<k)+1][k]);}void init(){    lg[0] = -1;    for (int i = 1; i < maxn; ++i)        lg[i] = lg[i>>1] + 1;}int seq[maxn];char str[maxn];void Del(int n, int Case){    int Max = 0;    string tmx, tmp;    for(int i = 1; i <= n/2; i++)    {        for(int j = 0; i*j+i < n; j++)        {            int l = rank[i*j];            int r = rank[i*j+i];            if(l > r) swap(l, r);            int x = querry(l+1, r);            int y = 0;            if(Max <= x/i + 1)            {                ///assign是string的一个赋值函数string.assign(const char *, int, int);                tmp.assign(str, i*j, i*(x/i+1));                if(x/i+1 > Max)                {                    Max = x/i+1;                    tmx = tmp;                }                else                {                    int xn = tmx.size();                    if(!xn || tmx > tmp)                    tmx = tmp;                }            }            int xp = i - x%i;            if(xp && j)            {                for(int k = xp; k < i; k++)                {                    l = rank[i*j-k];                    r = rank[i*j+i-k];                    if(l > r) swap(l, r);                    y = querry(l+1, r);                    int yp = y/i+1;                    if(yp < Max) continue;                    tmp.assign(str, i*j-k, i*yp);                    if(Max < yp)                    {                        tmx = tmp;                        Max = yp;                    }                    else                    {                        int yn = tmx.size();                        if(!yn || tmx > tmp)                            tmx = tmp;                    }                }            }        }    }    printf("Case %d: ",Case);    cout<<tmx<<endl;}int main(){    init();    int Case = 1;    while(scanf("%s", str) && str[0] != '#')    {        int n = strlen(str);        for(int i = 0; i < n; i++) seq[i] = str[i]-'a'+1;        seq[n] = 0;        da(seq, sa, n+1, 27);        calheight(seq, sa, n);        RMQ(n);        Del(n, Case++);    }    return 0;}


0 0
原创粉丝点击