题目描述】
对于给定的两个字符串a,b,我们定义a*b是将把它们连接在一起形成的字符串。例如,若a="abc",b="def",则a*b="abcdef"。如果我们将这种运算视为乘法,则非负整数的乘方运算被以类似的方式定义:a^0=""(空字符串),a^(n+1)=a*(a^n)。
【输入格式】
输入包含多组数据。
每组数据有一行一个大写字母组成的字符串s,其长度至少为1,至多为10^6.输入结束标志为一行一个“.”(半角句号)。
【输出格式】
输出使得存在某个a,使得a^n=s的最大n。
【样例输入】
ABCD AAAA ABABAB .
【样例输出】
1 4 3
题解:
容易题,可后缀数组被卡了常,于是上了KMP 显然答案即为 n/(n-next[n]+1)
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 using namespace std; 8 const int N=1e6+5; 9 char S[N];int n,s[N],c[50],rk[N],x[N],y[N],sa[N],k,f[N][22],high[N]; 10 void Getsa(){ 11 int m=29,t; 12 for(int i=0;i<=m;i++)c[i]=0; 13 for(int i=1;i<=n;i++)c[x[i]=s[i]]++; 14 for(int i=1;i<=m;i++)c[i]+=c[i-1]; 15 for(int i=n;i>=1;i--)sa[c[x[i]]--]=i; 16 for(k=1;k<=n;k<<=1){ 17 t=0; 18 for(int i=0;i<=m;i++)y[i]=0; 19 for(int i=n-k+1;i<=n;i++)y[++t]=i; 20 for(int i=1;i<=n;i++)if(sa[i]>k)y[++t]=sa[i]-k; 21 for(int i=0;i<=m;i++)c[i]=0; 22 for(int i=1;i<=n;i++)c[x[i]]++; 23 for(int i=1;i<=m;i++)c[i]+=c[i-1]; 24 for(int i=n;i>=1;i--)sa[c[x[y[i]]]--]=y[i]; 25 swap(x,y); 26 x[sa[1]]=t=1; 27 for(int i=2;i<=n;i++)x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?t:++t; 28 if(t==n)break; 29 m=t; 30 } 31 for(int i=1;i<=n;i++)rk[sa[i]]=i; 32 } 33 void Gethight(){ 34 int h=0,j; 35 for(int i=1;i<=n;i++){ 36 j=sa[rk[i]-1]; 37 if(h)h--; 38 for(;i+h<=n && j+h<=n;h++)if(s[i+h]!=s[j+h])break; 39 high[rk[i]-1]=h; 40 } 41 } 42 void prework(){ 43 int tmp,to; 44 for(int i=1;i<=n;i++)f[i][0]=high[i]; 45 for(int j=1;j<=21;j++){ 46 tmp=n-(1<<j)+1; 47 for(int i=1,to;i<=tmp;i++){ 48 to=i+(1<<(j-1)); 49 if(f[i][j-1]<f[to][j-1])f[i][j]=f[i][j-1]; 50 else f[i][j]=f[to][j-1]; 51 } 52 } 53 } 54 int query(int l,int r){ 55 int t=log(r-l+1)/log(2); 56 return min(f[l][t],f[r-(1<<t)+1][t]); 57 } 58 int lcp(int i,int j){ 59 if(rk[i]>rk[j])swap(i,j); 60 return query(rk[i],rk[j]-1); 61 } 62 void Getanswer(){ 63 int t,pp=n>>1; 64 for(int L=1;L<=pp;L++){ 65 if(n%L)continue; 66 t=lcp(1,1+L); 67 if(t==n-L){ 68 printf("%d ",n/L); 69 return ; 70 } 71 } 72 printf("1 "); 73 } 74 void work(){ 75 n=strlen(S+1); 76 for(int i=1;i<=n;i++)s[i]=S[i]-'A'+1; 77 Getsa();Gethight();prework(); 78 Getanswer(); 79 } 80 int main() 81 { 82 freopen("powerstrings.in","r",stdin); 83 freopen("powerstrings.out","w",stdout); 84 while(scanf("%s",S+1)){ 85 if(S[1]=='.')break; 86 work(); 87 } 88 return 0; 89 }
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 using namespace std; 8 const int N=1e6+5; 9 int net[N],n;char s[N]; 10 void work(){ 11 n=strlen(s+1);int t; 12 net[1]=1; 13 for(int i=2;i<=n;i++){ 14 t=net[i-1]; 15 while(t!=1 && s[t]!=s[i]) 16 t=net[t-1]; 17 if(s[t]==s[i])net[i]=t+1; 18 else net[i]=1; 19 } 20 if(!(n%(n-net[n]+1))) 21 printf("%d ",n/(n-net[n]+1)); 22 else printf("1 "); 23 } 24 int main() 25 { 26 freopen("powerstrings.in","r",stdin); 27 freopen("powerstrings.out","w",stdout); 28 while(scanf("%s",s+1)){ 29 if(s[1]=='.')break; 30 work(); 31 } 32 return 0; 33 }