AFO

[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);
	}
}

posted @ 2019-10-28 19:42  ZUTTER☮  阅读(83)  评论(0编辑  收藏  举报