[Poi2012]A Horrible Poem
[Poi2012]A Horrible Poem
判断len的长度是不是\(s_l\)到\(s_r\)的循环节只要看一下\(s_l\)到\(s_{r-len}\)和\(s_{l+len}\)到\(s_r\)是不是一样就行
首先如果是循环节的话一定是长度的约数,但是\(O(q\sqrt n)\) 的时间复杂度还是会T
如果l到r里面一共有k个a的话那么循环节个数一定要是a的个数的约数
这样就可以过了
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ULL unsigned long long
using namespace std;
const int base= 53;
const int M = 510001;
int n,m,k,s[M][26],l,r;
ULL a[M],p[M];
char c[M];
ULL ask(int l,int r)
{
return a[r]-a[l-1]*p[r-l+1];
}
int gcd(int x,int y)
{
if(!y) return x;
return gcd(y,x%y);
}
int main()
{
scanf("%d\n%s",&n,c+1);
for(int i=1;i<=n;i++) a[i]=a[i-1]*base+c[i]-'a'+1ull;
for(int i=1;i<=n;i++)
{
for(int j=0;j<26;j++) s[i][j]=s[i-1][j];
s[i][c[i]-'a']++;
}
p[0]=1;
for(int i=1;i<=n;i++) p[i]=p[i-1]*base;
scanf("%d",&m);
for(;m;m--)
{
scanf("%d%d",&l,&r);
int len=r-l+1, res=r-l+1;
for(int i=0;i<26;i++) len=gcd(len,s[r][i]-s[l-1][i]);
for(int i=1;i*i<=len;i++) if(len % i==0)
{
if(ask(l+(r-l+1)/i,r)==ask(l,r-(r-l+1)/i)) res=min(res,(r-l+1)/i);
if(ask(l+(r-l+1)/(len/i),r)==ask(l,r-(r-l+1)/(len/i))) res=min(res,(r-l+1)/(len/i));
}
printf("%d\n",res);
}
}