标签:
有两种实现方式:
1.二进制实现:
把xn 定界化为二进制表示的形式,然后用取余公式实现。如
x22=x2?x4?x16(原理是:22的二进制表示为10110)
然后计算:( ((x2%mod)?(x4%mod)%mod)?(x16%mod)%mod)%mod
2.递归实现(实际是二进制实现倒着的形式):
原理是:如果n是偶数就求(x?x)n/2 ,这样一直递归下去,直到n/2 为0为递归出口。如果n是奇数就求(x?x)n/2x ,这样一直递归下去,直到n/2 为0为递归出口。
二进制实现快速幂:
typedef long long LL;
LL mod(LL x, LL n, LL mod) {
LL res = 1;
while (n > 0) {
if (n & 1) res = res * (x % mod) % mod;
n >>= 1;
x = x * x;
}
return res;
}
递归实现代码
typedef long long LL;
LL mod(LL x, LL n, LL mod) {
if (n == 0) return 1;
LL res = mod(x * x % mod, n / 2, mod);
if (n & 1) res = res * x %mod;
return res;
}
UVa 10006的代码:
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
LL doit(LL x, LL n, LL mod) {
LL res = 1; //从2的0次方开始
while (n > 0) {
if (n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
bool isprime(int x) {
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) return false;
}
return x != 1;
}
int main(void)
{
int n;
while (scanf("%d", &n), n) {
bool ans = true;
if (isprime(n)) { printf("%d is normal.\n", n); continue; }
for (int i = 2; i < n; i++) {
if (doit(i, n, n) != i) {
ans = false;
break;
}
}
if (ans) printf("The number %d is a Carmichael number.\n", n);
else printf("%d is normal.\n", n);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/jibancanyang/article/details/47172575