如果我们要求X^n次方;
当n很大的时候;
会GG;
这个时候就会用到快速幂算法了, 顾名思义, 快速幂, 快速求幂。
因为任何一个数都可以用2进制表示。
比如9 = 2 ^3 + 2^0;
7 = 2^2 + 2^ 1 + 2 ^0;
所以我们可以把n看成 n = 2 ^ k1 + 2 ^ k2 + 2^k3...... 这样来表示。
当然我们同样可以把x用这样表示。
即 x = x ^(2^k1) * x ^ (2 ^ k2)* ......
若n = 22;
x ^ 22 = x^ 16 * x ^ 4 * x ^ 2;
22转化成二进制是10110。
直接看代码
模板 :
#include<bits/stdc++.h>
using namespace std;
#define clr(x) memset(x, 0, sizoef(x))
typedef long long ll;
const int mod = 100000007;
ll mod_pow(ll x, ll n, ll mod)
{
ll res = 1;
while(n > 0)
{
if(n & 1) // 判断2进制的n的末尾是否为1;有1则代码构成成分中含有这个 2 ^ k。
res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
int main()
{
ll x, n;
scanf("%lld %lld", &x, &n); // 求x 的n 次方
printf("%lld\n", mod_pow(x, n, mod));
return 0;
}
l例题 :: Uva 10006(挑战这本书上有)
#include<bits/stdc++.h>
using namespace std;
#define clr(x) memset(x, 0, sizeof(x))
typedef long long ll;
const int MAXN = 65005;
int prim[MAXN];
void init()
{
clr(prim);
prim[0] = 1;
prim[1] = 1;
for(int i = 2; i < MAXN; i++)
{
if(prim[i] == 1)
continue;
for(int j = i + i; j < MAXN; j = j + i)
{
prim[j] = 1;
}
}
}
ll mod_pow(ll x, ll n, ll mod)
{
ll res = 1;
while(n > 0)
{
if(n & 1)
res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
int main()
{
ll n;
init();
while(~scanf("%lld", &n) && n)
{
int flag = 1;
if(prim[n] == 0)
flag = 0;
if(flag)
for(int i = 1; i < n; i++)
{
if(i != mod_pow(i, n, n))
{
flag = 0;
break;
}
}
if(flag)
printf("The number %lld is a Carmichael number.\n", n);
else
printf("%lld is normal.\n", n);
}
return 0;
}