【POJ】3693 Maximum repetition substring

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4 #define MAXN 100010
  5 #define MAXM 20
  6 char s[MAXN];
  7 int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN];
  8 int sa[MAXN],height[MAXN],rk[MAXN];
  9 int st[MAXM][MAXN],log2[MAXN];
 10 int len[MAXN];
 11 inline bool cmp(int *r,int a,int b,int len)
 12 {
 13     return r[a]==r[b]&&r[a+len]==r[b+len];
 14 }
 15 void SA(int n,int m)
 16 {
 17     int i,j,p,*x=wa,*y=wb,*t;
 18     for(i=0;i<m;i++)
 19         ws[i]=0;
 20     for(i=0;i<n;i++)
 21         ws[x[i]=s[i]]++;
 22     for(i=1;i<m;i++)
 23         ws[i]+=ws[i-1];
 24     for(i=n-1;i>=0;i--)
 25         sa[--ws[x[i]]]=i;
 26     for(j=p=1;p<n;j<<=1,m=p)
 27     {
 28         for(p=0,i=n-j;i<n;i++)
 29             y[p++]=i;
 30         for(i=0;i<n;i++)
 31         {
 32             if(sa[i]>=j)
 33                 y[p++]=sa[i]-j;
 34         }
 35         for(i=0;i<m;i++)
 36             ws[i]=0;
 37         for(i=0;i<n;i++)
 38             ws[wv[i]=x[y[i]]]++;
 39         for(i=1;i<m;i++)
 40             ws[i]+=ws[i-1];
 41         for(i=n-1;i>=0;i--)
 42             sa[--ws[wv[i]]]=y[i];
 43         for(t=x,x=y,y=t,x[sa[0]]=0,p=i=1;i<n;i++)
 44             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
 45     }
 46 }
 47 void Height(int n)
 48 {
 49     int i,j,k;
 50     for(i=1;i<=n;i++)
 51         rk[sa[i]]=i;
 52     for(i=k=0;i<n;height[rk[i++]]=k)
 53         for(k?k--:0,j=sa[rk[i]-1];s[i+k]==s[j+k];k++);
 54 }
 55 void Init()
 56 {
 57     int i,k;
 58     log2[1]=0;
 59     for(i=k=2;i<MAXN;i++)
 60     {
 61         if(i>=(1<<k))
 62             k++;
 63         log2[i]=k-1;
 64     }
 65 }
 66 void ST(int n)
 67 {
 68     int i,j;
 69     for(i=1;i<=n;i++)
 70         st[0][i]=height[i];
 71     for(j=1;(1<<j)<=n;j++)
 72     {
 73         for(i=1;i+(1<<j)<=n+1;i++)
 74             st[j][i]=min(st[j-1][i],st[j-1][i+(1<<(j-1))]);
 75     }
 76 }
 77 int LCP(int i,int j)
 78 {
 79     i=rk[i];
 80     j=rk[j];
 81     if(i>j)
 82         swap(i,j);
 83     i++;
 84     int k=log2[j-i+1];
 85     return min(st[k][i],st[k][j-(1<<k)+1]);
 86 }
 87 int main()
 88 {
 89     int n,ca=1;
 90     int i,j,k,temp,res,ans,pos,cnt,bg;
 91     Init();
 92     while(scanf(" %s",s),s[0]!='#')
 93     {
 94         n=strlen(s);
 95         SA(n+1,'z'+1);
 96         Height(n);
 97         ST(n);
 98         ans=0;
 99         for(i=1;i<=(n>>1);i++)
100         {
101             for(res=j=0;j+i<=n;j+=i)
102             {
103                 k=LCP(j,j+i);
104                 temp=k/i+1;
105                 pos=j-(i-k%i);
106                 if(pos>=0&&LCP(pos,pos+i)>=i)
107                     temp++;
108                 res=max(res,temp);
109             }
110             if(res>ans)
111             {
112                 ans=res;
113                 cnt=0;
114                 len[cnt++]=i;
115             }
116             else if(res==ans)
117                 len[cnt++]=i;
118         }
119         for(i=1;i<=n;i++)
120         {
121             for(j=0;j<cnt;j++)
122             {
123                 if(sa[i]+len[j]<=n&&LCP(sa[i],sa[i]+len[j])>=len[j]*(ans-1))
124                     break;
125             }
126             if(j!=cnt)
127                 break;
128         }
129         printf("Case %d: ",ca++);
130         temp=sa[i]+len[j]*ans;
131         for(k=sa[i];k<temp;k++)
132             putchar(s[k]);
133         putchar('\n');
134     }
135     return 0;
136 }
原文地址:https://www.cnblogs.com/DrunBee/p/2582016.html