快速幂运算
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。
直接看代码
模板 :
当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; }