- Step1 Problem
原题
一个非素数n,如果对于任意2<=a<=n-1的a都有a^n mod n =a,则称n是一个卡迈克尔数,给出一整数n,判断其是否是卡迈克尔数
- Step2 Ideas:
首先判断n是不是素数,不是素数直接枚举a快速幂算出a^n是否等于a即可,时间复杂度O(nlogn),包含两种求快速幂的方法,递归和循环
- Step3 Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
using namespace std;
const int maxn = 650005;
bool vis[maxn];
void prime()
{
mem(vis, true);
for(int i = 2; i*2 <= maxn; i++)
{
if(vis[i])
{
for(int j=i+i; j<=maxn; j+=i) vis[j] = false;
}
}
}
ll quick_mod(ll a,ll n,ll mod)///递归求快速幂
{
if(n == 0) return 1;
ll x = quick_mod(a, n/2, mod);
ll ans = x * x % mod;
if(n%2 == 1) ans = ans * a % mod;
return ans;
}
//ll quick_mod(int a,int b,int mod)//普通求快速幂
//{
// ll ans=1;
// ll t=a;
// while(b)
// {
// if(b&1)
// ans=ans*t%mod;
// t=t*t%mod;
// b>>=1;
// }
// return ans;
//}
int main()
{
int n;
prime();
while(~scanf("%d", &n))
{
if(!n) break;
if(vis[n]) printf("%d is normal.
", n);
else
{
bool ok = true;
for(int i = 2; i < n; i++)
{
if(quick_mod(i, n, n) != i)
{
ok = false;
break;
}
}
if(ok) printf("The number %d is a Carmichael number.
", n);
else printf("%d is normal.
", n);
}
}
return 0;
}