UVa 10006 - Carmichael Numbers

来源:互联网 发布:网络都市色情长篇小说 编辑:程序博客网 时间:2024/05/22 15:37
/*数学:素数 + 模运算Carmichael Number:1)非素数2)通过 Fermat Pass所以,程序要完成两个工作。1) 判断n是否为素数2) 测试对于 2 <= a <= n-1,是否满足 a^n mod n = a工作1:由于n很小,可以用筛素数法。工作2:求a^n mod n,可以使用分冶法优化。对于任务2还可以优化,a不必取所有 [2,n-1],只需要取小于n的素数。证明如下: 如果 a=b*c, b、c为素数。如果b^n mod n = b, c^n mod n = c,则a^n mod n = (b*c)^n mod n = (b^n mod n ) * (c^n mod n) = bc = a,所以只需要测试素数即可。*/#include <cstdio>#include <cmath>#include <cstring>using namespace std;const int MAXN = 65004;int vis[MAXN];int prime[MAXN];int cnt = 0;void set_prime(){    int m = sqrt(MAXN) + 1;    int i;    for(i=2; i<=m; i++) if(!vis[i]) {        prime[cnt++] = i;        for(int j=i*i; j<MAXN; j+=i) {            vis[j] = 1;        }    }    for(; i<MAXN; i++) {        if(!vis[i]){            prime[cnt++] = i;        }    }}int pow_mod(int a, int n, int m){    if(n == 1) return a;    long long ans =  pow_mod(a, n/2, m);    ans = ans * ans % m;    if(n%2 == 1) ans = ans * a % m;    return (int)ans;}int main() {    #ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);    #endif    set_prime();    int n;    while(scanf("%d", &n) == 1 && n) {        if(!vis[n]) {            printf("%d is normal.\n", n);            continue;        }        int found = 1;        for(int i=0; prime[i]<n; i++) {            int a = prime[i];            if(pow_mod(a, n, n) != a) {                found = 0;                break;            }        }        if(found) {            printf("The number %d is a Carmichael number.\n", n);        } else {            printf("%d is normal.\n", n);        }    }    return 0;}

原创粉丝点击