标签:href ++ ima bsp div csdn min return c++
题目链接:hdu 2459 Maximum repetition substring
题意:
让你找一个重复最多的子串,并且输出。
题解:
这个是论文题,看的cxlove的题解,不是很理解为什么这样就能完全找完,当作结论使吧。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 namespace suffixarray{ 5 #define FN(n) for(int i=0;i<n;i++) 6 const int N =1E5+7;//字符串长度 7 int rnk[N],sa[N],height[N],c[N];char s[N]; 8 void getsa(int n,int m,int *x=rnk,int *y=height){ 9 FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i]; 10 for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i; 11 for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){ 12 for(int i=n-k;i<n;i++)y[p++]=i; 13 FN(n)if(sa[i]>=k)y[p++]=sa[i]-k; 14 FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i]; 15 for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i]; 16 swap(x,y),p=1,x[sa[0]]=0; 17 for(int i=1;i<n;i++) 18 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; 19 } 20 FN(n)rnk[sa[i]]=i; 21 for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k) 22 for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++); 23 } 24 } 25 using namespace suffixarray; 26 27 int f[N][20],ans[N],cas; 28 void rmq(int *a,int n) 29 { 30 for(int i=1;i<=n;i++)f[i][0]=a[i]; 31 for(int j=1;1<<j<n;j++)for(int i=1;i<=n;i++) 32 if(i+(1<<j)-1<=n)f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]); 33 else break; 34 } 35 inline int find(int l,int r) 36 { 37 l=rnk[l],r=rnk[r]; 38 if(l>r)swap(l,r); 39 l++; 40 int k=31-__builtin_clz(r-l+1); 41 return min(f[l][k],f[r-(1<<k)+1][k]); 42 } 43 44 int main() 45 { 46 while(scanf("%s",s),s[0]!=‘#‘) 47 { 48 int len=strlen(s); 49 getsa(len+1,130); 50 rmq(height,len); 51 int cnt=0,mx=0; 52 F(l,1,len-1)for(int i=0;i+l<len;i+=l) 53 { 54 int r=find(i,i+l); 55 int step=r/l+1,k=i-(l-r%l); 56 if(k>=0&&r%l)step+=(find(k,k+l)>=r); 57 if(step>mx) 58 { 59 mx=step,cnt=0; 60 ans[cnt++]=l; 61 }else if(step==mx)ans[cnt++]=l; 62 } 63 int tmp=-1,st; 64 for(int i=1;i<=len&&tmp==-1;i++)F(j,0,cnt-1) 65 { 66 int l=ans[j]; 67 if(find(sa[i],sa[i]+l)>=(mx-1)*l) 68 { 69 tmp=l,st=sa[i]; 70 break; 71 } 72 } 73 printf("Case %d: ",++cas); 74 for(int i=st,j=0;j<tmp*mx;j++,i++) printf("%c",s[i]); 75 printf("\n"); 76 } 77 return 0; 78 }
hdu 2459 Maximum repetition substring(后缀数组)
标签:href ++ ima bsp div csdn min return c++
原文地址:http://www.cnblogs.com/bin-gege/p/6367338.html