[Hash] A Horrible Poem A Horrible Poem (string hash + number theory)

[Link] title

# 10038. "one through 2.1 Exercise 4" A Horrible Poem

Reference [blog]

A Horrible Poem (string hash + number theory)


Description [title]

Is given by the lower case letters a string  S S, then gives  Q Q a query, the answer requires  S S shortest substring of a loop section.
If the string  B B string  A circular section A, then  A A may be composed of  B was repeated several times to give B.

[Algorithm] - for first length  L E n- substring len, the cycle length of the section  x Sufficient Conditions of x: [ . 1 , L E n- - x ] [. 1, len-x] is equal to the hash value string  [ X + . 1 , L E n- ] [X +. 1, len] hash value string.


Minimum Cycle length is assumed that the section of the original string length len apparently len * k. If there is only k, k, and the prime factor decomposition sequentially, in addition to each sample k, the obtained k . k. Len and the product is still circulating section, the use of this property. Washed successively with prime factor  i i test than n, if the cycle is still removed section on the i belongs to k, it is removed, leaving the result len.

 

 [Code]:

 1 #include<cstdio>
 2 #include<bitset>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef unsigned long long ULL ;
 7 const int N = 5e5+10;
 8 ULL h[N],p[N],base = 131;
 9 
10 char str[N];
11 int n,m,len,ans,tmp,L,R;
12 
13 int prime[N],Min_p[N],cnt;
14 void Init(){
15     //memset( is_prime , true , sizeof is_prime );
16     int tot = 0 ;
17     for(int i=2;i<N;i++) {
18         if(!Min_p[i]) {
19             //if( i < 10 ) printf("%d\n",i);
20             prime[++tot]=i;
21             Min_p[i]=i;
22         }
23         for(int j=1;j<=tot;j++) {
24             if(prime[j]>Min_p[i]||prime[j]*i>N) break;
25             Min_p[prime[j]*i]=prime[j];
26         }
27     }
28     cnt = tot ;
29 }
30 
31 void get_Hash(){
32     p[0] = 1;
33     for(int i=1;i<=len;i++){
34         p[i] = p[i-1] * base ;
35         h[i] = h[i-1] * base + (ULL) str[i];
36     }
37 }
38 
39 bool Vaild( int L , int R , int k ){
40     return h[R] - h[L+k-1] * p[len-k] == h[L + (len/k-1)*k - 1] - h[L-1] * p[len-k] ;
41 }
42 int main()
43 {
44     Init();
45     //for(int i=1;i<10;i++) printf("%d\n",prime[i]);
46     scanf("%d%s%d",&n,str+1,&m);
47 
48 
49     len  = strlen( str+1 ) ;
50     get_Hash();
51     /*
52     for(int i=1;i<=len;i++){
53         printf("%llu\n",h[i]);
54     }
55     */
56     while( m-- ){
57         scanf("%d%d",&L,&R);
58         len = tmp = ans = R - L + 1 ;
59         while( tmp != 1  ){
60             int k = Min_p[tmp] ;
61             while( tmp % k == 0 && Vaild(L,R,ans/Min_p[tmp] ) )
62                 tmp /= k , ans /= k ;
63             while( tmp % k == 0 )
64                 tmp /= k ;
65         }
66         printf("%d\n",ans);
67     }
68     return 0 ;
69 }

 

Guess you like

Origin www.cnblogs.com/Osea/p/11324796.html