比较基本的数论题目,不过《挑战程序设计》上说这个题有不用幂运算求解的两种方法,一种复杂度为根号n,一种是O(n)预处理,O(1)判定,我还没有想出来....
快速幂的方法:
1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 using namespace std; 5 6 typedef long long ll; 7 const int N = 65001; 8 bool visit[N]; 9 10 void sieve( int n ) 11 { 12 int r = sqrt( n + 0.5 ); 13 memset( visit, 0, sizeof(visit) ); 14 visit[0] = visit[1] = 1; 15 for ( int i = 2; i <= r; i++ ) 16 { 17 if ( !visit[i] ) 18 { 19 for ( int j = i * i; j <= n; j += i ) 20 { 21 visit[j] = 1; 22 } 23 } 24 } 25 } 26 27 ll pow_mod( ll a, ll n, ll mod ) 28 { 29 ll ans = 1, w = a % mod; 30 while ( n ) 31 { 32 if ( n & 1 ) 33 { 34 ans = ans * w % mod; 35 } 36 w = w * w % mod; 37 n >>= 1; 38 } 39 return ans; 40 } 41 42 int main () 43 { 44 sieve( N - 1 ); 45 int n; 46 while ( cin >> n, n ) 47 { 48 bool flag = true; 49 if ( visit[n] ) 50 { 51 for ( int x = 2; x < n; x++ ) 52 { 53 int tmp = pow_mod( x, n, n ); 54 if ( tmp != x ) 55 { 56 flag = false; 57 break; 58 } 59 } 60 } 61 else 62 { 63 flag = false; 64 } 65 if ( flag ) 66 { 67 cout << "The number " << n << " is a Carmichael number." << endl; 68 } 69 else 70 { 71 cout << n << " is normal." << endl; 72 } 73 } 74 return 0; 75 }