这个算法本身就不难。
poj1961
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; char ss[1100000]; int p[1100000]; int main() { int n,T_T=0; while(scanf("%d",&n)!=EOF) { if(n==0)break; printf("Test case #%d ",++T_T); scanf("%s",ss+1); p[0]=0;int j=0; for(int i=2;i<=n;i++) { while(j>0&&ss[i]!=ss[j+1])j=p[j]; if(ss[i]==ss[j+1])j++; p[i]=j; } for(int i=2;i<=n;i++) if(i%(i-p[i])==0&&(i/(i-p[i]))>1)printf("%d %d ",i,i/(i-p[i])); printf(" "); } return 0; }
最小表示法裸题:bzoj1398
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int len; char s[2][1100000]; int getmin(int w) { for(int i=1;i<=len;i++)s[w][i+len]=s[w][i]; int i=1,j=2; while(i<=len&&j<=len) { int k=0; while(k<=len&&s[w][i+k]==s[w][j+k])k++; if(k==len)break; if(s[w][i+k]>s[w][j+k]) { i=i+k+1; if(i==j)i++; } else { j=j+k+1; if(j==i)j++; } } return min(i,j); } int main() { scanf("%s",s[0]+1);len=strlen(s[0]+1); scanf("%s",s[1]+1); if(len!=strlen(s[1]+1)){printf("No ");return 0;} int be0=getmin(0); int be1=getmin(1); bool bk=true; for(int i=1;i<=len;i++) { if(s[0][be0]!=s[1][be1]){bk=false;break;} be0++;if(be0==len+1)be0=1; be1++;if(be1==len+1)be1=1; } if(bk==false)printf("No "); else { printf("Yes "); for(int i=1;i<=len;i++) { printf("%c",s[0][be0]); be0++;if(be0==len+1)be0=1; } printf(" "); } return 0; }