题意:判断一个数n(2 < n < 6500)是否是一个Carmichael数,
成立条件:1、是合数;
2、对于任意一个2<= a <= n-1,都是有a^n mod n = a。
——>>刚学了个矩阵快速幂,想起还有个快速幂取模,找到这题,核心思想与矩阵快速幂是一样的,另外加上个合数的判断,判断方法可先打素数表,二分查找。
另外有个重大发现,那个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 查看评论