快速幂运算

来源:互联网 发布:关于现代武器的软件 编辑:程序博客网 时间:2024/05/22 01:50

如果我们要求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;}



0 0
原创粉丝点击