bzoj 2795 [Poi2012]A Horrible Poem hash+数论

2795: [Poi2012]A Horrible Poem

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 640  Solved: 322
[Submit][Status][Discuss]

Description


Given a string S consisting of lowercase English letters, and then give q queries, asking to answer the shortest cyclic section of a substring of S.
If string B is a cyclic section of string A, then A can be obtained by repeating B several times.

Input

 

The first line contains a positive integer n (n<=500,000), which represents the length of S.
The second line contains n lowercase English letters, representing the string S.
The third line contains a positive integer q (q<=2,000,000), indicating the number of queries.
The following q lines have two positive integers a,b (1<=a<=b<=n) in each line, indicating the length of the shortest loop section of the query string S[a..b].

 

Output

Output q rows of positive integers in turn, and the positive integers in the i-th row correspond to the answer to the i-th query.

 

Sample Input

8
aaabcabc
3
1 3
3 8
4 8

Sample Output

1
3
5

 %%https://blog.csdn.net/ww140142/article/details/48260615

 1 #include<cstring>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<iostream>
 6 #include<vector>
 7 
 8 #define G 29
 9 #define N 500007
10 #define mod 1000000007
11 #define ll long long
12 
13 #define Wb putchar(' ')
14 #define We putchar('\n')
15 #define rg register int
16 using namespace std;
17 inline int read()
18 {
19     int x=0,f=1;char ch=getchar();
20     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
21     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
22     return x*f;
23 }
24 inline void write(int x)
25 {
26     if(x<0) putchar('-'),x=-x;
27     if (x==0) putchar(48);
28     int num=0;char c[15];
29     while(x) c[++num]=(x%10)+48,x/=10;
30     while(num) putchar(c[num--]);
31 }
32 
33 int n,Q;
34 char ch[N];
35 ll bin[N],hash[N];
36 bool flag[N];
37 vector<int>ve[N];
38 
39 void init_prime()
40 {
41     for (rg i=2;i<=n;i++)
42         if (!flag[i])
43         {
44             rg x=i;
45             while(x<=n)
46             {
47                 int z=x;
48                 while(z%i==0) ve[x].push_back(i),z/=i;
49                 flag[x]=true;
50                 x+=i;
51             }
52         }
53 }
54 bool judge(int x,int l,int r)
55 {
56     ll res1=hash[r-x]-(hash[l-1]*bin[(r-x)-l+1])%mod;
57     ll res2=hash[r]-(hash[l+x-1]*bin[(r-x)-l+1])%mod;
58     res1=(res1%mod+mod)%mod,res2=(res2%mod+mod)%mod;
59     return res1==res2;
60 }
61 int main()
62 {
63     n=read(),scanf("%s",ch+1),bin[0]=1,init_prime();
64     for (int i=1;i<=n;i++)
65         hash[i]=(hash[i-1]*G+ch[i]-'a')%mod,bin[i]=(bin[i-1]*G)%mod;
66     Q=read();
67     while(Q--)
68     {
69         int l=read(),r=read(),num=r-l+1,ans=num;
70         if (num==1) write(1),We;
71         else 
72         {
73             for (rg i=0;i<ve[num].size();i++)
74                 if (judge(ans/ve[num][i],l,r)) ans/=ve[num][i];
75             write(ans),We;
76         }
77     }
78 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325211441&siteId=291194637