快速幂,快速幂求逆元

快速幂

acwing875.快速幂

可以快速求在O(log k)复杂度下出 akmod p 的结果(1a,p,k109)

如果是n组数据,时间复杂度就是O(nlogk)

基本思路

1.先预处理出来a20,a21,...,a2logk这k个数
2.将aka20,a21,...,a2logk这k个数来组合,即组合出ak = a2x1a2x2...a2xt = a2x1+2x2+...+2xt

ps: 为什么 k 可以用 20,21,22,...2logk 中的数凑出来?
答: 2log2k=k 所以一定可以凑出k

如何组合出ak

将k看成二进制形式

如果最后一位为1则乘上当前位的权,并将权乘个a倍变成下一个位的权


例子:凑a5,5写为二进制为101

1.最后一位为1,此位权为a20,res = 1*a20,将权改成a倍变成下一位权a21,将二进制数101最后一位去掉变成二进制数10

2.最后一位为0,此位权为a21,res = 1*a20不变,将权改成a倍变成下一位权a22,将二进制数10最后一位去掉变成二进制数1

3.最后一位为1,此位权为a22,res = 1*a20a22,将权改成a倍变成下一位权a23,将二进制数10最后一位去掉变成二进制数1

所以 res = a5 就可以计算出来


所以步骤就是,只要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;
}

快速幂求逆元

acwing876.快速幂求逆元

欧拉定理与费马小定理

欧拉定理:若ap互质,则aφ(p)1mod(p)

费马小定理:若p为质数,则ap11mod(p)

互质:如果两个数的公约数只有1,则这两个数互质

思路


此题给了p一定为质数,就用欧拉定理推论费马小定理来求逆元即可

a/bax(modm),则称 x 为 b 的模 m 乘法逆元
两边同乘b得 aabx(modm)
1bx(modm)
bx1(modm)

若b和m互质 是 存在(b模m的)乘法逆元x 的充要条件。
由费马小定理得 bm1bx1(modm),因此 x=bm2


题中给定a、p其中p为质数,求a模p的乘法逆元。
分为两种情况:
1.如果a和p互质,有ap11mod(p),所以答案为 ap2
2.如果a和p不互质,不存在逆元

那么求ap2使用快速幂即可

代码

#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;
}
posted @   r涤生  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示