Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

Uva - 10006 - Carmichael Numbers

$
0
0

题意:判断一个数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;
}


作者:SCNU_Jiechao 发表于2013-3-16 23:51:35 原文链接
阅读:35 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>