2 hints:
- need long long to calculate multiple-mode, int may overflow;
- check whether the number is a prime at first, as prime need verify all the numbers smaller than it, it consume much time.
codes:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <assert.h>
#include <algorithm>
#include <math.h>
#include <ctime>
#include <functional>
#include <string.h>
#include <stdio.h>
#include <numeric>
#include <float.h>
using namespace std;
vector<bool> isPrime(65010, true);
void getPrime() {
int q = sqrt((double)65000);
for (int i = 2; i <= q; i++) {
if (isPrime[i]) {
for (int j = i + i; j < 65010; j += i) {
if (isPrime[j]) {
isPrime[j] = false;
}
}
}
}
}
int modMul(int a, int n) {
int mn = n;
long long result = a;
n--;
long long exp = 1, pow = a;
while (n > 0) {
pow *= pow;
pow %= mn;
exp *= 2;
if (n >= exp) {
n -= exp;
result *= pow;
result %= mn;
}
else {
n -= 1;
exp = 1;
pow = a;
result *= a;
result %= mn;
}
if (n == 0) break;
}
return result;
}
bool isAPrime(int num) {
return isPrime[num];
}
bool isCalm(int num) {
for (int f = 2; f < num; f++) {
if (modMul(f, num) != f) {
return false;
}
}
return true;
}
int main() {
getPrime();
int i;
while (cin >> i) {
if (i == 0) break;
if (!isAPrime(i) && isCalm(i))
cout << "The number " << i << " is a Carmichael number." << endl;
else
cout << i << " is normal." << endl;
}
return 0;
}