What power is fast
This article is to help a student learn to write ksm
Baidu Baike to the definition:
As the name implies, quick power is the rapid calculation of n-th power base number. Its time complexity is O (log₂N), as compared with the efficiency of simple O (N) has been greatly improved.
This is a way to quickly compute the \ (a ^ b \) algorithm values of
If violence computing \ (a ^ b \) need to take a b own times, when b is too large, it will time out.
Use ksm log₂b only used once, the number of calculations is greatly reduced.
principle:
The multiply themselves a = a * a \ (a ^ 2 \) , do the same operation \ (a * 2 ^ a ^ a ^ = 2. 4 \) ; multiplied by itself n times so that after a \ (a ^ 2n \) .
\ (A ^ a ^ x * y = a ^ (x + y) \)
For B, as long as it is a positive integer, it can be split into several different powers of 2 is added.
Such as: 11 = \ (2 ^ 2 ^ 3 + 1 + 2 ^ 0 \)
11 is the binary 1011, which is stored in computer form, is more convenient to carry out the above-described split for b.
process:
Definition of two numbers, temp and ans; temp is the number to be raised to the initial value of the above-mentioned a; ans initial value of 1, that is the answer, (1 Why is it, think for themselves).
while(b)//也就是当b大于0时
First determine whether the last bit b 1
If will ans * = temp;
if(b&1) ans=(1longlong*ans*temp);
About 1 & b:
"&" is "bit with."
x & y is binary x and y are each a result "and calculating" the.
And arithmetic: that both will return to 1 1 0 otherwise.
& 1 then b
b = 1011
1 = 0001
b = 0001 & 1
because the previous several 1 are all 0,
so only the last bit is a binary b 1, b & 1 will return 1.
Very clever, and soon.
After squaring temp, it becomes \ (A ^ 2 \) ;
B while the right one.
That is: If b = 11 (10), binary b = 1011 (2);
A right becomes b = 101 (2);
temp=(1longlong*temp*temp);
b=>>1;
Until the condition is not satisfied while repeating the above process b> 0;
Code:
For example to luoguP1226
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll b,p,k;
ll ksm(ll a,ll b,ll z)//快速幂函数
{
//这里的temp可以直接用a来表示,不影响结果,可以自己想为什么
ll ans=1;
while(b)
{
if(b&1) ans=(1ll*ans*a)%z;
a=(1ll*a*a)%z//自乘
b>>=1;//右移
}
return ans;
}
int main()
{
scanf("%lld%lld%lld",&b,&p,&k);
printf("%lld^%lld mod %lld=%lld",b,p,k,ksm(b,p,k)%k);
return 0;
}