時間限制: 1 Sec 內存限制: 512 MBc++
題面謝絕公開。spa
吃字符串可海星……正解KMP,然而我就是用hash水過233333。blog
直接串內匹配,看是否能拆成更小的字符串。從小到大枚舉長度,不是約數直接跳過,是約數再匹配。內存
預處理一個hash前綴和直接搞就完了。字符串
代碼:hash
#include<bits/stdc++.h> #define int long long #define rint register int #define ull unsigned long long using namespace std; const int Z=2333; int T,n,m,ans,len,blo; ull hs[1000006],JZ[1000006]; char ch[1000006]; bool _ok; signed main() { // freopen("ex_ccx2.in","r",stdin); // freopen("my.out","w",stdout); scanf("%lld",&T); while(T--) { scanf("%lld %lld %s",&n,&m,ch+1);JZ[0]=1; if(m==1){printf("%lld\n",n-1);continue;} bool te=1; for(rint i=1;i<=m;++i) { hs[i]=hs[i-1]*Z+(ch[i]-'A'+1); if(ch[i]!='A')te=0; JZ[i]=JZ[i-1]*Z; } if(te){printf("%lld\n",n*m-1);continue;} if(n*m<=1000000) { ans=0;JZ[0]=1; for(rint i=1;i<=n;++i) for(rint j=1;j<=m;++j) { rint lin=(i-1)*m+j; hs[lin]=hs[lin-1]*Z+(ch[j]-'A'+1); JZ[lin]=JZ[lin-1]*Z; } for(rint i=1;i<n*m;++i) if(hs[i]==hs[n*m]-hs[n*m-i]*JZ[i])ans=i; printf("%lld\n",ans); continue; } len=0,blo=0; for(rint i=1;i<=(m/2);++i) { if(m%i!=0)continue;_ok=1; for(rint j=2;j<=(m/i);++j) if((hs[i*(j-1)]-hs[i*(j-2)]*JZ[i])!=(hs[j*i]-hs[i*(j-1)]*JZ[i])){_ok=0;break;} if(_ok){len=i,blo=m/len;break;} } printf("%lld\n",(n-1)*m+(blo-1)*len); } return 0; }