埃及筛模版+欧拉筛模版
int prime[N];//素数 bool vis[N];//埃及筛标记 int cnt;//素数个数 void Is_prime()//埃氏筛 { memset(vis,0,sizeof(vis)); cnt=0; for(int i=2;i<=N;++i)//从最小素数2开始,遍历每一个数 { if(!vis[i]) { prime[cnt++]=i;//如果没有访问过,将这个数存到素数表里 for(int j=i*i;j<=N;j+=i)//接着筛去它的倍数 vis[j]=1; } } } void Oula_prime()//欧拉筛 { memset(vis,0,sizeof(vis)); cnt=0; for(int i=2;i<=N;++i) { if(!vis[i]) prime[cnt++]=i; for(int j=1;j<=cnt&&i*prime[j]<=N;++j)//较埃及筛更快,原因是每个数只会被自己的最小素数筛一次 { vis[i*prime[j]]=1; if(i%prime[j]==0) break; } } }
快速幂模版
typedef long long ll; ll first_pow(ll a,ll b,ll mod)//a^b%mod { ll res=1; while(b) { if(b&1)//判断b是否为奇数 res=res*a%mod; b>>=1; a=a*a%mod; } return res%mod; }
话不多说,上题目!
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int cnt;
bool vis[65001];
void init(void){//埃氏筛法
cnt = 0;
memset(vis, 0, sizeof(vis));
for(long long i = 2; i <= 65000; ++i)
{
if(!vis[i]){
for(long long j = i * i; j <= 65000; j += i)
vis[j] = 1;
}
}
}
long long fast_pow(long long a, long long b, long long mod)//a^b%mod
{
long long res = 1;
while(b){
if(b & 1)
res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res % mod;
}
int main()
{
init();
int n;
while(scanf("%d", &n) != EOF && n){
if(!vis[n]){
printf("%d is normal.\n", n);
continue;
}
bool flag = true;
for(int i = 2; i < n; ++i){
if(fast_pow(i, n, n) != i)//快速幂验证a^n%n=a
{
flag = false;
break;
}
}
if(flag){ //不是素数但是通过了费马小定理
printf("The number %d is a Carmichael number.\n", n);
}
else{
printf("%d is normal.\n", n);
}
}
return 0;
}
如有错误,欢迎指出!