题意:
如果一个不是素数的数n满足从2到n-1中取一个数a满足a^n mod n = a
则这个数为Carmichael Numbers。判断输入的n是不是Carmichael Numbers。
要注意的是:快速幂中乘法可能超过int,要用long long强制转换。
先判断是不是素数,如果是,则直接输出is normal。不必要做快速幂了,否则超时。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define maxn 65100
using namespace std;
bool vis[maxn];
void init()
{
int m = sqrt(65000+0.5);
memset(vis,0,sizeof(vis));
for(int i = 2;i<= m;i++)
{
if(!vis[i])
{
for(int j = i*i;j<=65000;j+=i)
vis[j] = true;
}
}
}
int quick_pow(int a,int n,int mod)
{
int ans = 1;
while(n)
{
if(n&1)
ans = ((long long)ans*a)%mod;
a = ((long long)a*a)%mod;
n >>= 1;
}
return ans;
}
int main()
{
int n;
init();
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
int flag = 0;
if(!vis[n])
{
printf("%d is normal.\n",n);
continue;
}
for(int i=2;i<=n-1;i++)
{
if(quick_pow(i,n,n)!=i)
{
flag = 1;
break;
}
}
if(flag)
printf("%d is normal.\n",n);
else printf("The number %d is a Carmichael number.\n",n);
}
return 0;
}