The initial state is in the fractional form) decimal point conversion principle: n/m;
N/= gcd (n, m );
M/= gcd (n, m );
N = n % m;
For (I: 0 .....)
N * = k;
Bit [I] = n/m; (retain the value of each bit)
N % = m;
Question: Calculate the length and start position of the cyclic sequence of the decimal point of n/m;
Assume that the number of I in the initial cycle is n and is recorded as ni. Then, the number of j is n, and the number of j is nj. Then, the cyclic sequence appears, then the length of the cyclic sequence is L = j-I.
Based on the decimal point calculation principle, there will be nj = (ni * 2 ^ L) % m; ----> 2 ^ L % m = 1% m; (t is used here)
When m and 2 are mutually Prime, according to Euler's theorem, there are 2 ^ phi (m) = 1% m, because 2 ^ 0 = 1, so the starting point is 0; that is, question 1;
When the two are not mutually reinforcing, then m % 2! = 0;
Therefore, to simplify the equivalence, the two sides are divided by the power of 2 at the same time (so that m interacts with 2 until the condition of the Euler's function is met), then there will be 2 ^ (L-t) = 1% (m/(2 ^ t). We can see that the starting point of the cyclic sequence is t, that is, t + 1 of the question;
The final requirement is 2 ^ L' = 1% M'. Because 2 ^ k = 1% m', when k % M = 0, the valid value is obtained, the maximum value is obtained by enumerating the phi (m') factor from small to large.
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<bitset> #include<iomanip> using namespace std; int t, n, m, GCD, phi, ans1, ans2; int temp, num; int fac[1000000]; int gcd( int a , int b ) { return b == 0 ? a : gcd( b , a % b ); } int euler(int n) { int ret=1,i; for (i=2;i*i<=n;i++) if (n%i==0) { n/=i,ret*=i-1; while (n%i==0) n/=i,ret*=i; } if (n>1) ret*=n-1; return ret; } int Pow( int a , int b , int c ) { int ans = 1 ; while( b > 0 ) { if( b & 1 ) { ans = ( long long ) ans * a % c ; } b >>= 1 ; a = ( long long )a * a % c ; } return ans ; } int main() { int Case = 1 ; while( scanf( "%d/%d" , &n , &m ) != EOF ) { GCD = gcd( n , m ) ; n /= GCD ; m /= GCD ; t = 0 ; while( m % 2 == 0 ) { t++ ; m /= 2 ; } ans1 = t + 1 ; phi = euler( m ) ; if( phi == 1 ) { ans2 = 1 ; } else { int num = 0 ; for( int i = 1 ; i * i <= phi ; ++i ) { if( phi % i == 0 ) { fac[ num++ ] = i ; fac[ num++ ] = phi / i ; } } sort( fac , fac + num ) ; for( int i = 0 ; i < num ; ++i ) { temp = Pow( 2 , fac[ i ] , m ) ; if( temp == 1 ) { ans2 = fac[ i ] ; break ; } } } printf( "Case #%d: %d,%d\n" , Case++ , ans1 , ans2 ) ; } return 0 ; } #include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<bitset>#include<iomanip>using namespace std;int t, n, m, GCD, phi, ans1, ans2;int temp, num;int fac[1000000]; int gcd( int a , int b ){return b == 0 ? a : gcd( b , a % b );}int euler(int n){int ret=1,i;for (i=2;i*i<=n;i++)if (n%i==0){n/=i,ret*=i-1;while (n%i==0)n/=i,ret*=i;}if (n>1)ret*=n-1;return ret;}int Pow( int a , int b , int c ){int ans = 1 ; while( b > 0 ){if( b & 1 ){ans = ( long long ) ans * a % c ;}b >>= 1 ;a = ( long long )a * a % c ;}return ans ;} int main(){int Case = 1 ;while( scanf( "%d/%d" , &n , &m ) != EOF ){GCD = gcd( n , m ) ;n /= GCD ;m /= GCD ;t = 0 ;while( m % 2 == 0 ){t++ ;m /= 2 ;}ans1 = t + 1 ;phi = euler( m ) ;if( phi == 1 ){ans2 = 1 ; }else{int num = 0 ;for( int i = 1 ; i * i <= phi ; ++i ){if( phi % i == 0 ){fac[ num++ ] = i ;fac[ num++ ] = phi / i ;}}sort( fac , fac + num ) ;for( int i = 0 ; i < num ; ++i ){temp = Pow( 2 , fac[ i ] , m ) ;if( temp == 1 ){ans2 = fac[ i ] ; break ;}}}printf( "Case #%d: %d,%d\n" , Case++ , ans1 , ans2 ) ;}return 0 ;}