//求一个串最多由哪个串复制若干次得到 poj 2406

来源:互联网 发布:如何下载spss20软件 编辑:程序博客网 时间:2024/06/06 15:03

用kmp会很方便。

后缀数组的话枚举字符串(0,i),如果能够被n整除并且lcp(0,i+1)==n-i-1,那么答案就是n/(i+1);

//求一个串最多由哪个串复制若干次得到#include <iostream>#include <string>#include <cmath>#include <map>using namespace std;const int N=5000005;int wa[N],wb[N],wv[N],wsum[N];int height[N],sa[N],rank[N];int n;char str[N];int f[N];bool vis[N];int r[N];int ans;#define F(x) ((x)/3+((x)%3==1?0:tb))#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)int c0(int *r,int a,int b){return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2];}int c12(int k,int *r,int a,int b){if(k==2)return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1);elsereturn r[a]<r[b]||r[a]==r[b]&&wv[a+1]<wv[b+1];}void sort(int *r,int *a,int *b,int n,int m){    int i;    for(i=0;i<n;i++) wv[i]=r[a[i]];    for(i=0;i<m;i++) wsum[i]=0;    for(i=0;i<n;i++) wsum[wv[i]]++;    for(i=1;i<m;i++) wsum[i]+=wsum[i-1];    for(i=n-1;i>=0;i--) b[--wsum[wv[i]]]=a[i];    return;}void dc3(int *r,int *sa,int n,int m){     int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;     r[n]=r[n+1]=0;     for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i;     sort(r+2,wa,wb,tbc,m);     sort(r+1,wb,wa,tbc,m);     sort(r,wa,wb,tbc,m);     for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++)     rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++;     if(p<tbc) dc3(rn,san,tbc,p);     else for(i=0;i<tbc;i++) san[rn[i]]=i;     for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3;     if(n%3==1) wb[ta++]=n-1;     sort(r,wb,wa,ta,m);     for(i=0;i<tbc;i++) wv[wb[i]=G(san[i])]=i;     for(i=0,j=0,p=0;i<ta && j<tbc;p++)     sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++];     for(;i<ta;p++) sa[p]=wa[i++];     for(;j<tbc;p++) sa[p]=wb[j++];     return;}void calheight(int *r,int *sa,int n){int i,j,k=0;for(i=0;i<=n;i++)rank[sa[i]]=i;for(i=0;i<n;height[rank[i++]]=k)for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);}int mmin(int x,int y){return x<y?x:y;}/*void rmqinit(int n){int i,j,m,k;m=floor(log(1.0*n)/log(2.0));for(i=1;i<=n;i++)f[i][0]=height[i];for(i=1;i<=m;i++)for(j=n;j>=1;j--){f[j][i]=f[j][i-1];k=1<<(i-1);if(j+k<=n)f[j][i]=mmin(f[j][i],f[j+k][i-1]);}}*/void rmqinit2(int n){int i,s=n-sa[rank[0]];for(i=rank[0];i>=1;i--){f[i]=s;s=mmin(s,height[i]);}s=N;for(i=rank[0]+1;i<=n;i++){s=mmin(s,height[i]);f[i]=s;}}/*int get_rmq(int x,int y){int m,t;x=rank[x];y=rank[y];if(x>y)          t=x,x=y,y=t;      x++;      m=floor(log(1.0*(y-x+1))/log(2.0));      return mmin(f[x][m],f[y-(1<<m)+1][m]);  }*/int main(){int T,i,j,k,ca=0,s,t;scanf("%d",&T);while(~scanf("%s",str)){if(str[0]=='.')break;n=strlen(str);for(i=0;i<n;i++)  r[i]=(int)str[i]; r[n]=0;dc3(r,sa,n+1,127);calheight(r,sa,n);rmqinit2(n);//for(i=1;i<=n;i++)//cout<<i<<' '<<f[i]<<endl;for(i=0;i<n;i++)if(n%(i+1)==0){s=f[rank[i+1]];if(s==n-i-1){ans=n/(i+1);break;}}printf("%d\n",ans);}return 0;}


原创粉丝点击