您的位置:首页 > 其它

快速幂运算

2017-04-14 17:30 162 查看
如果我们要求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
== 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  题解 模板