spoj-687(後綴數組+RMQ)

spoj-687(後綴數組+RMQ)

題目:
A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed string t with length l>=1. For example, the string
s = abaabaabaaba
is a (4,3)-repeat with t = aba as its seed string. That is, the seed string t is 3 characters long, and the whole string s is obtained by repeating t 4 times.
Write a program for the following task: Your program is given a long string u consisting of characters ‘a’ and/or ‘b’ as input. Your program must find some (k,l)-repeat that occurs as substring within u with k as large as possible. For example, the input string
u = babbabaabaabaabab
contains the underlined (4,3)-repeat s starting at position 5. Since u contains no other contiguous substring with more than 4 repeats, your program must output the maximum k.
Input

In the first line of the input contains H- the number of test cases (H <= 20). H test cases follow. First line of each test cases is n - length of the input string (n <= 50000), The next n lines contain the input string, one character (either ‘a’ or ‘b’) per line, in order.
Output

For each test cases, you should write exactly one interger k in a line - the repeat count that is maximized.
Example

Input:
1
17
b
a
b
b
a
b
a
a
b
a
a
b
a
a
b
a
b

Output:
4
since a (4, 3)-repeat is found starting at the 5th character of the input string.

啊,,wa了好幾次又re了都是因爲自己的zz細節錯誤啊。。。按照論文裏的套板子就好。。。

AC代碼:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<complex>
#include<queue>
#define T 111111
using namespace std;
char s[T],ccc[T];
int t1[T],t2[T],cc[T],x[T],sa[T],rnk[T],height[T];
int f[T][20];
int len;
int ans;
bool cmp(int *y,int a,int b,int k)
{
    int a1=y[a];
    int b1=y[b];
    int a2=a+k>=len ? -1:y[a+k];
    int b2=b+k>=len ? -1:y[b+k];
    return a1==b1 && a2==b2;
}
int make_sa()
{
    int *x=t1,*y=t2;
    int m=255;
    for(int i=0; i<m; i++) cc[i]=0;
    for(int i=0; i<len; i++) ++cc[x[i]=s[i]];
    for(int i=1; i<m; i++) cc[i]+=cc[i-1];
    for(int i=len-1; i>=0; i--) sa[--cc[x[i]]]=i;

    for(int k=1; k<=len; k<<=1)
    {
        int p=0;
        for(int i=len-k; i<len; i++) y[p++]=i;
        for(int i=0; i<len; i++)
           if( sa[i]>=k ) y[p++]=sa[i]-k;

        for(int i=0; i<m; i++) cc[i]=0;
        for(int i=0; i<len; i++) ++cc[x[y[i]]];
        for(int i=1; i<m; i++) cc[i]+=cc[i-1];
        for(int i=len-1; i>=0; i--) sa[--cc[x[y[i]]]]=y[i];

        swap(x,y);
        m=1; x[sa[0]]=0;
        for(int i=1; i<len; i++)
          x[sa[i]]=cmp(y,sa[i],sa[i-1],k) ? m-1:m++;

        if( m>=len ) break;
    }
}
void make_height()
{
    for(int i=0; i<len; i++) rnk[sa[i]]=i;
    height[0]=0;
    int k=0;
    for(int i=0; i<len; i++)
    {
        if(!rnk[i]) continue;
        int j=sa[rnk[i]-1];
        if(k) k--;
        while(s[i+k]==s[j+k]) k++;
        height[rnk[i]]=k;
    }
}
void rmq()
{
    for(int i=0;i<len;i++){
        f[i][0]=height[i];
    }
    int nlog=int(log(double(len))/log(2.0));
    for(int j=1;j<=nlog;j++){
        for(int i=0;i<len;i++){
            if(i+(1<<j)<=len){
                f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
            }
        }
    }
}
int qrmq(int l,int r)
{
    l=rnk[l];
    r=rnk[r];
    if(l>r){
        int h;
        h=l;l=r;r=h;
    }
    l++;
    int nlog=int (log(double(r-l+1))/log(2.0));
    return min(f[l][nlog],f[r-(1<<nlog)+1][nlog]);
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&len);
        int ii=0;
        while(ii!=len){
            scanf("%s",ccc);
            s[ii++]=ccc[0];
        }
        s[ii]='\0';
        make_sa();
        make_height();
        rmq();
        ans=0;
        for(int k=1;k<len;k++){
            for(int i=0;i+k<len;i+=k){
                int n=qrmq(i,i+k);
                //cout<<"n:"<<n<<endl;
                int sum=(n/k)+1;

                int pos=i-(k-n%k);
                if(pos>=0&&n%k!=0) {
                    if(qrmq(pos,pos+k)>=k)
                        sum++;
                }
                ans=max(ans,sum);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章