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;}