快速幂 Quick pow
作者:互联网
本文使用非递归方法,即二进制
对于 \(a^p\) 来说,如果把 p 写成二进制,那么他就可以写成诺干的的二次幂的和。例如 13 的二进制 1101,在 3 号位,2号位以及0 号位都是 1,那么 \(13=2^3+2^2+2^0=8+4+1\)。所以 \(a^{13} =a^8*a^4*a^1\)。
同理,我们可以把 \(a^p\) 表示为 \(a^{2^k} ...a^2,a^1\) 中若干的积。若二进制对应的 \(i\) 号位为 1 ,即代表 \(a^{2^i}\) 被选中,于是得到了计算思路。
- 初始一个 \(res=1\) 用来存放结果。
- 判断 \(p\) 的二进制末尾是否为1,是的话就乘上 \(a\) 的值。
- 平方 \(a\) 并把 \(p\) 右移一位。
其中,判断二进制末尾是否为1可以理解为判断是否为奇数,右移一位可以理解为p/2。
最后,放上一道并不是那么模板的模板题。
洛谷P2613
\(Code\)
#include<bits/stdc++.h>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define gc getchar
#include<algorithm>
#define reg register
#define ll long long
#define int long long
using namespace std;
const int N=1e5+5;
const int mod=19260817;
const int INF = 0x3f3f3f3f;
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (((res << 1) + (res << 3) + (ch ^ '0'))%mod); return f ? (-res)%mod : (res)%mod;}
int a,b;
inline int quick_pow(int x,int p)
{
int res=1;
while(p)
{
if(p & 1) res=((res%mod)*(x%mod))%mod;
x=((x%mod)*(x%mod))%mod;
p >>= 1;
}
return res;
}
signed main()
{
a=read(),b=read();
if(!b)
{
printf("Angry!");
return 0;
}
b=quick_pow(b,mod-2);
printf("%lld",((a%mod)*(b%mod))%mod);
return 0;
}
标签:ch,int,pow,二进制,res,Quick,include,快速,mod 来源: https://www.cnblogs.com/Alwaysmaxx/p/16496660.html