这题思路挺神
循环节一定是长度的约数 && i是[l,r]这一段的循环节的充要条件是[l,r-i]和[l+i,r]相匹配 那么很明显可以hash 还有就是要存一下这一段每个字符的个数 循环节一定是gcd(k,cnt) k为每个字母的个数 cnt为当前的得到的gcd cnt的初值为r-l+1
可恶的是cout居然RE
贴代码
#include<bits/stdc++.h>
#define mod 1000000007
#define base 233
using namespace std;
const int N=5e5+5;
char s[N];
int n,T,cnt,pre[N][27];
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
long long f[N],tmp[N];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int get(int x,int l){
return ((f[x+l-1]-f[x-1]*tmp[l])%mod+mod)%mod;
}
bool judge(int x,int y,int l){
int L=y-x+1;
if(get(x,L-l)==get(x+l,L-l)) return 1;return 0;
}
int main() {
n=read();
scanf("%s",s+1);
T=read();
tmp[0]=1;
for(int i=1; i<=n; i++) {
tmp[i]=tmp[i-1]*base%mod;
f[i]=(f[i-1]*base+s[i]-96)%mod;
for(int j=1; j<=26; j++)
pre[i][j]=pre[i-1][j];
pre[i][s[i]-96]++;
}
while(T--) {
int x=read(),y=read();
cnt=y-x+1;
for(int i=1;i<=26;i++)
cnt=gcd(cnt,pre[y][i]-pre[x-1][i]);
int ans=0,L=y-x+1;
for(int i=1;i*i<=cnt;i++)
if(cnt%i==0) {
if(judge(x,y,L/(cnt/i))){
ans=L/(cnt/i);
break;
}
else if(judge(x,y,L/i)) ans=L/i;
}
printf("%d\n",ans);
}
}