題意:詢問字符串指定區間循環節個數。
解法:有循環節長度a的字符串s[x,y]的性質:s[x,y-a]==s[x+a,y]由此寫一個雙hash就行了。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<string> #include<queue> using namespace std; #ifdef WIN32 #define LL "%I64d" #else #define LL "%lld" #endif #define MAXN 1100000 #define MAXV MAXN*2 #define MAXE MAXV*2 #define INF 0x3f3f3f3f #define INFL 0x3f3f3f3f3f3f3f3fLL #define PROB "password" #define _a 29 #define _b 131 #define mod 1000000007 typedef unsigned long long qword; inline int nextInt() { char ch; int x=0; bool flag=false; do ch=getchar(),flag=(ch=='-')?true:flag; while(ch<'0'||ch>'9'); do x=x*10+ch-'0'; while (ch=getchar(),ch<='9' && ch>='0'); return x*(flag?-1:1); } int n,m; char str[MAXN]; pair<qword,qword> hs[MAXN]; bool pflag[MAXN]; int prime[MAXN],topp=-1; qword pow_a[MAXN]; qword pow_b[MAXN]; void init() { int i,j; for (i=2;i*i<MAXN;i++) { if (!pflag[i]) prime[++topp]=i; for (j=0;j<=topp && i*prime[j]<MAXN;j++) { pflag[i*prime[j]]=true; if (i%prime[j]==0)break; } } pow_a[0]=1; pow_b[0]=1; for (i=1;i<MAXN;i++) pow_a[i]=pow_a[i-1]*_a%mod, pow_b[i]=pow_b[i-1]*_b; } pair<qword,qword> hash(int x,int y) { pair<qword,qword> ret; ret.first=((hs[x].first+mod-hs[y+1].first*pow_a[(y+1)-x]%mod)%mod+mod)%mod;/*Attention*/ ret.second=hs[x].second-hs[y+1].second*pow_b[(y+1)-x]; return ret; } int check(int x,int y) { int ret=1; int len=(y-x+1); int lo=len; int a,i; for (i=0;i<=topp && prime[i]*prime[i]<=len;i++) { if (len%prime[i]==0) { a=1; while (len%prime[i]==0) { len/=prime[i]; a*=prime[i]; if (hash(x,y-lo/a)==hash(x+lo/a,y)) { ret*=prime[i]; } } } } if (len>1) { a=len; if (hash(x,y-lo/a)==hash(x+lo/a,y)) { ret*=a; } } return ret; } int main() { freopen(PROB".in","r",stdin); //freopen(PROB".out","w",stdout); int i,j,k; int x,y,z; int ans; init(); scanf("%d ",&n); fgets(str,sizeof(str),stdin); hs[n]=make_pair(1,1); for (i=n-1;i>=0;i--) { hs[i].first=hs[i+1].first*_a%mod+str[i]-'a'+1; hs[i].second=hs[i+1].second*_b+str[i]-'a'+1; } // pr3=hash(5,5); scanf("%d",&m); for (i=0;i<m;i++) { scanf("%d%d",&x,&y); x--;y--; printf("%d ",(y-x+1)/check(x,y)); } return 0; }