【快速幂 && 素数筛 && 数论】Carmichael Numbers

 

  • 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", 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", n);
            else printf("%d is normal.\n", n);
        }
    }
    return 0;
}
posted @ 2019-02-21 16:32  Mr.XuAMis.Liu  阅读(273)  评论(0编辑  收藏  举报