最小表示算法。。。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cstdlib> #include<cmath> using namespace std; const int maxlen=1e6+5; template<typename T> inline void read(T &a){ a=0;T b=1;char x=getchar(); while(x<‘0‘||‘9‘<x){ if(x==‘-‘)b=-1; x=getchar(); } while(‘0‘<=x&&x<=‘9‘){ a=(a<<1)+(a<<3)+x-‘0‘; x=getchar(); } a*=b; } char ch[50]; int temp; template<typename T> inline void print(T a){ if(a<0){ putchar(‘-‘); a=-a; } do{ ch[++temp]=a%10+‘0‘; a/=10; }while(a); while(temp)putchar(ch[temp--]); } char s[maxlen]; int next[maxlen],len; inline void kmp_init(){ int p=0; for(int i=2;i<=len;i++){ while(s[p+1]!=s[i] && p)p=next[p]; if(s[p+1]==s[i])p++; next[i]=p; } } int kmp(int p){ //递归求解最小表示长度 奇数个or偶数个 if(!next[p])return p; if(next[p]*2==p){ return kmp(next[p]); } else if( !(p%(p-next[p]*2)) ){ int ans=kmp(p-next[p]); return !(p%ans) ? ans : p; } else return p; } inline int judge(int pp){ int ans=0,p=0,last=0; for(int i=1;i<=len;i++){ while(s[p+1]!=s[i]&&p)p=next[p]; if(s[p+1]==s[i])p++; if(i-p!=last)break; if(p==pp){ ans++; p=next[p]; last=i; } } return ans; } int main(){ while(gets(s+1)!=NULL){ memset(next,0,sizeof(next)); len=strlen(s+1); kmp_init(); if(next[len]){ if(len%(len-next[len])==0)print(len/(len-next[len]));
//告诉我们一个道理:next[i]不一定<(i/2),瞬间变得简单了 else print(1); } else print(1); putchar(‘\n‘); } return 0; }
原文:https://www.cnblogs.com/a-blog-of-taojiayi-2003/p/10981589.html