Http: // 162.105.81.212/judgeonline/problem? Id = 3358
Question:
The decimal numbers p and q are given, P/q are expressed as binary decimal places, and the starting position of the binary decimal point and the length of the loop section are obtained.
Input:
P/Q (P> = 0, q> 0, p, q <2e10)
Output:
Case # N: S, L (n test cases, S is the starting position of the loop section, L is the length of the loop section)
Idea Source: http://hi.baidu.com/lonewind/blog/item/2e7475dbb794bb64d1164e4f.html
Solution:
The simplest algorithm for calculating cyclic knots is to use iterative methods to obtain the remainder of the first repeated occurrence.
So X1 = P, XK = x (k-1) * 2 mod q, until xn = P, the length of the loop section is n-1, but this question gives a large range of data, if this algorithm is used, it will execute many operations, possibly hundreds of millions of times. In addition, the remainder operation is relatively slow, and the time efficiency of this algorithm cannot be guaranteed, the time limit for this question is 1 s, so we need to find a better algorithm.
First, we need to simplify P/Q, and use gcd (p, q) to obtain the maximum common divisor of the two, and remove this number at the same time. The following calculation can be optimized, next, first obtain the starting position of the cyclic section. Because the binary decimal point is obtained, the denominator needs to be decomposed. P/q = P/(R * 2 ^ m) = (t + K * r)/(R * 2 ^ m) = (T/R + k) * 1/(2 ^ m ). Since p and q are mutually qualitative, T and R are also mutually qualitative, and K is an integer, which does not affect the decimal part. Another 1/(2 ^ m) only causes the decimal point to shift to the left, only the starting position of the cycle section is affected, but the length is not affected. Because both R and T and 2 are quality, we can see that the starting position of the cycle section of T/R is 1, the decimal point is shifted to the left M bit, so the starting position of the P/Q cycle is m + 1. The following problem is to find the cycle length of T/R, and this problem can be converted to the minimum K value that satisfies T * 2 ^ K = T (mod R, the above formula can be further simplified, (T * 2 ^ K) mod r = (T mod R) * (2 ^ K mod R) moD r = T * (2 ^ K mod R) mod r = T, so the problem is simplified to the minimum K value that satisfies 2 ^ k = 1 (mod R.
If the above problem is just simple enumeration, when R is a prime number, it may need to calculate the R-1 times, the calculation is quite large, so the Euler's theorem is introduced here.
Any integerNCan be expressed as the product of its prime factor:N = p1 ^ Q1 * P2 ^ Q2 *......* PM ^ Qm,Then its Euler function is:Diameter (n) = p1 ^ (q1-1) * (p1-1) * P2 ^ (q2-1) * (p2-1 )*......* PM ^ (QM-1) * (pm-1), Further simplifiedPhi (n) = N * (1-1/P1) * (1-1/P2 )*......* (1-1/pm), IfAAndNMutual quality, thenA ^ PHI (n) = 1 (mod N).
# Include <iostream> <br/> # include <algorithm> <br/> # include <cmath> <br/> using namespace STD; <br/> const int maxn = 1000000; <br/> int A [maxn]; <br/>__ int64 Mod (_ int64 A, _ int64 B, _ int64 N) // a ^ B mod n; <br/>{< br/>__ int64 res = 1; <br/> while (B) <br/>{< br/> If (B & 1) <br/> res = res * A % N; <br/> A = (_ int64) A * A % N; <br/> B >>= 1; <br/>}< br/> return res; <br/>}< br/>__ int64 gcd (_ int64 A, _ int64 B) <br/>{< br/> If (B = 0) return a; <br/> return gcd (B, A % B ); <br/>}< br/>__ int64 Euler (_ int64 X) // evaluate a single Euler function, <br/>{< br/>__ int64 I, res = x; <br/> for (I = 2; I <(_ int64) SQRT (x * 1.0) + 1; I ++) <br/> If (X % I = 0) <br/>{< br/> res = Res/I * (I-1 ); <br/> while (X % I = 0) <br/> X/= I; <br/>}< br/> If (x> 1) res = Res/x * (X-1); <br/> return res; <br/>}< br/> int main () <br/>{< br/>__ int64 p, q, oulasum, Ans; <br/> int T = 1, Len, I, j, X; <br/> char S; <br/> while (scanf ("% i64d % C % i64d", & P, & S, & Q )! = EOF) <br/>{< br/> If (P = 0) <br/> {printf ("case # % d: 0, 0/N ", t ++); Continue ;}< br/> // P/= gcd (p, q); // Add wa ??? <Br/> q/= gcd (p, q); <br/> Len = 0; <br/> while (! (Q & 1) // Q % 2 = 0, calculate the non-cyclic length <br/>{< br/> q> = 1; // q = q> 1; <br/> Len ++; <br/>}< br/> If (q = 1) <br/> {printf ("case # % d: 1, 1/N", t ++); Continue ;}< br/> oulasum = Euler (Q ); // evaluate the Euler's function of q <br/> x = 0; <br/> for (I = 2; I * I <= oulasum; I ++) // enumerate the factors of the Euler's function; if it is from 2 to the oulasum enumeration, it will time out. <Br/>{< br/> If (oulasum % I = 0) <br/>{< br/> A [x ++] = I; <br/> A [x ++] = oulasum/I; // speed up, optimization <br/>}< br/> A [x ++] = oulasum; <br/> sort (A, A + x ); <br/> for (I = 0; I <X; I ++) // 2 ^ k = 1 (mod R) <br/> If (mod (2, A [I], q) = 1) <br/>{< br/> ans = A [I]; <br/> break; <br/>}< br/>/* <br/> ans = oulasum; <br/> for (I = 2; I * I <= oulasum; I ++) <br/> {<br/> If (oulasum % I = 0 & Mod (2, I, q) = 1) <br/> if (I <ans) ans = I; <br/> If (oulasum % I = 0 & Mod (2, oulasum/I, q) = 1) <br/> If (oulasum/I <ans) ans = oulasum/I; <br/>}< br/> */<br/> printf ("case # % d: % d, % d/N", t ++, Len + 1, ans); <br/>}< br/> return 0; <br/>}
Resolution:Let's take a look at the 1/10 data set. According to the Binary Conversion Method (multiplication method), we can get:
1/10 2/10 4/10 8/10 16/10 32/10... then all molecules subtract 10 as much as possible and get: 1/10 2/10 4/10 8/10 6/10... at this time, we find that there are duplicates, so this repetition is the minimum loop we require.
Abstract The model as follows: P/Q
First, p '= P/gcd (p, q)
q'=q/gcd(p,q);
Then we calculate p '* 2 ^ I = P' * 2 ^ J (mod Q') ("=" indicates the same remainder, I <j)
After transformation, the following results are obtained:
P '* 2 ^ I * (2 ^ (J-I)-1) = 0 (mod Q ')
That is, Q' | P' * 2 ^ I * (2 ^ (J-I)-1)
Because gcd (P', Q') = 1,
Obtain: Q' | 2 ^ I * (2 ^ (J-I)-1)
Because 2 ^ (J-I)-1 is an odd number, Q 'has the power of 2, I is, and I is the first digit at the starting position of the loop.
So that q'' is the number after the power of Q' is removed.
Q'' | 2 ^ (J-I)-1
That is, to obtain X, so that 2 ^ x = 1 (mod q '')
Q ''and 2 are mutually qualitative, so there must be a solution, and this is a high-order homogeneous equation, there is a classic method to do, you can go to the information to solve.
FromLearning Space of j_factory
This question is to calculate the division of two numbers P/Q. The decimal part of the result is represented in binary. When q is not a power of 2, this binary is a 01 string of a wireless loop.
The following is a simulated decimal part in binary format. It can be found that binary data transmission has a loop, Because p = P % Q, since it is a loop, it is also a mode operation, this is related to the order of P Modulo q. The order of P % Q must be a factor of the Euler's function of Q. In this way, it is converted into a modulo equation: p * 2 ^ n = x (mod q). Of course, p and q must be mutually Prime, and 2 and Q must be mutually Prime. Remove 2 from Q before calculation. p and q are the same as the maximum public factor. Then, start from 1, and then enumerate the factors of the number.
# Include <stdio. h> <br/> # define PR printf <br/> int main () <br/>{< br/> int I, p, q; <br/> while (scanf ("% d", & P, & Q) = 2) {<br/> PR ("0. "); <br/> for (I = 1; I <= 100; I ++) <br/> {<br/> P * = 2; <br/> PR ("% d", P/Q); <br/> P = P % Q; <br/>}< br/> PR ("/N "); <br/>}< br/>/* <br/> 5 192 <br/> 0.000001101010101010101010101010101010101010101010101010101010101010101010101010 <br/> 1010101010101010101010 <br/> */