快速幂,快速幂求逆元
快速幂
可以快速求在O(log )复杂度下出 mod 的结果()
如果是n组数据,时间复杂度就是O()
基本思路
1.先预处理出来这k个数
2.将用这k个数来组合,即组合出 = =
ps: 为什么 可以用 中的数凑出来?
答: 所以一定可以凑出k
如何组合出
将k看成二进制形式
如果最后一位为1则乘上当前位的权,并将权乘个a倍变成下一个位的权
例子:凑,5写为二进制为101
1.最后一位为1,此位权为,res = 1*,将权改成a倍变成下一位权,将二进制数101最后一位去掉变成二进制数10
2.最后一位为0,此位权为,res = 1*不变,将权改成a倍变成下一位权,将二进制数10最后一位去掉变成二进制数1
3.最后一位为1,此位权为,res = 1*,将权改成a倍变成下一位权,将二进制数10最后一位去掉变成二进制数1
所以 res = 就可以计算出来
所以步骤就是,只要b不为0
如果b的二进制最后一位为1则res乘上当前权
权变为原来平方
b最后一位去掉
注意
凡是中间结果可能会溢出的地方,都要特殊处理:
1.快速幂的结果都要开long long,快速幂计算过程中res和权要开long long
2.可能溢出的地方(res、权)都要取模
代码
#include<iostream>
using namespace std;
typedef long long LL;
LL qmi(int a,int b,int p)
{
LL res = 1 % p;
while(b)
{
if(b & 1) res = res * a % p;
a = (LL)a * a % p; // 这里要开LL
b >>= 1;
}
return res;
}
int main()
{
int n;
scanf("%d",&n);
while(n --)
{
int a,b,p;
scanf("%d%d%d",&a,&b,&p);
printf("%lld\n",qmi(a,b,p));
}
return 0;
}
快速幂求逆元
欧拉定理与费马小定理
欧拉定理
:若与互质,则
费马小定理
:若为质数,则
互质
:如果两个数的公约数只有1,则这两个数互质
思路
此题给了p一定为质数,就用欧拉定理推论费马小定理来求逆元即可
,则称 x 为 b 的模 m 乘法逆元
两边同乘b得
即
同
若b和m互质 是 存在(b模m的)乘法逆元x 的充要条件。
由费马小定理得 ,因此
题中给定a、p其中p为质数,求a模p的乘法逆元。
分为两种情况:
1.如果a和p互质,有,所以答案为
2.如果a和p不互质,不存在逆元
那么求使用快速幂即可
代码
#include<iostream>
using namespace std;
typedef long long LL;
LL pmi(int a,int k,int p) // a^k mod p
{
LL res = 1 ;
while(k)
{
if(k&1) res = res * a % p;
a = (LL) a * a % p;
k >>= 1;
}
return res;
}
int main()
{
int n;
scanf("%d",&n);
while(n --)
{
int a,p;
scanf("%d%d",&a,&p);
if(a % p == 0) puts("impossible"); // p为质数,a<p必然互质,a>p只要不是p的倍数必然互质
else printf("%lld\n",pmi(a,p-2,p));
}
return 0;
}
rds_blogs
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效