Uva - 10006 - Carmichael Numbers

题意:判断一个数n(2 < n < 6500)是否是一个Carmichael数,

成立条件:1、是合数;

2、对于任意一个2<= a <= n-1,都是有a^n mod n = a。

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=12&problem=947

——>>刚学了个矩阵快速幂,想起还有个快速幂取模,找到这题,核心思想与矩阵快速幂是一样的,另外加上个合数的判断,判断方法可先打素数表,二分查找。

另外有个重大发现,那个mod的n是不变的(就是输入的n),而那个指数n是变化的。

#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 65000 + 10;
int p[maxn], cnt;
bool vis[maxn];

void prime_table()      //筛素数
{
    memset(vis, 0, sizeof(vis));
    for(int i = 2; i < maxn; i++) if(!vis[i])
        for(int j = (i<<1); j < maxn; j += i) vis[j] = 1;
    cnt = 0;
    for(int i = 2; i < maxn; i++)
        if(!vis[i]) p[cnt++] = i;
}
bool bs(int* A, int x, int y, int v)        //二分查找
{
    int m;
    while(x < y)
    {
        m = x + (y-x) / 2;
        if(A[m] == v) return 1;
        else if(A[m] > v) y = m;
        else x = m+1;
    }
    return 0;
}
int pow_mod(int a, int n, int m)        //二分幂取模
{
    if(n == 1) return a % m;
    long long x = pow_mod(a, n/2, m);
    long long ans = x * x % m;
    if(n&1) ans = ans * a % m;
    return ans;
}
int main()
{
    int n;
    prime_table();
    while(~scanf("%d", &n))
    {
        if(!n) return 0;
        bool ok = 0;
        if(!bs(p, 0, cnt, n))
        {
            ok = 1;
            for(int i = 2; i <= n-1; i++)
                if(pow_mod(i, n, n) != i)
                {
                    ok = 0;
                    break;
                }
        }
        if(ok) printf("The number %d is a Carmichael number.\n", n);
        else printf("%d is normal.\n", n);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值