Carmichael Numbers
原文链接 http://huiming.io/2013/05/24/carmichael-numbers.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
分析:只要注意到当n为偶数时
(a^n) mod n = (((a^(n/2)) mod n)*((a^(n/2)) mod n)) mod n
当n为奇数时
(a^n) mod n = (((a^(n/2)) mod n)*((a^(n/2)) mod n)*a) mod n
则(a^n) mod n运算可在O(log(n))的时间内完成。<!--more-->
另外:本答案会导致超时(TLE),优化的方案是:先把65000以内的所有Carmichael数计算出来!其实不过区区十几个数而已。
#include <iostream>
#include <cmath>
using namespace std;
typedef unsigned int uint;
bool prime(uint n) {
if (n % 2 == 0)
return false;
uint i = 3;
uint h = sqrt(n) + 1;
while (i <= h) {
if (n % i == 0)
return false;
i += 2;
}
return true;
}
uint mod(uint a, uint n, uint m) {
if (n == 1)
return a;
uint x = mod(a, n / 2, m);
x = (x * x) % m;
if (n % 2)
x = (x * a) % m;
return x;
}
bool carm(uint n) {
bool r = true;
for (int i = 2; i < n; i++) {
if (mod(i, n, n) != i) {
r = false;
break;
}
}
if (r && prime(n))
r = false;
return r;
}
int main() {
uint n;
while (cin >> n && n) {
if (carm(n))
cout << "The number " << n << " is a Carmichael number." << endl;
else
cout << n << " is normal." << endl;
}
return 0;
}