AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

算法基础课笔记

作者: 作者的头像   Moon_light ,  2019-10-14 23:19:04 ,  所有人可见 ,  阅读 2329


3


3

算法基础课的笔记:

扩展欧几里得算法求逆元

对于求a * x ≡ 1 (mod p)中的乘法逆元,即求x,由欧几里得算法可以得出,原式中的x等价于
式 a * x + p * y = 1中的x
所以我们可以利用扩展欧几里得算法来求乘法逆元

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long LL;

int n,p;

void exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x = 1;
        y = 0;
    }
    else
    {
        exgcd(b,a%b,y,x);
        y -= a/b*x;
    }
}

int main()
{
    cin>>n;

    while(n --)
    {
        int a,p,x,y;

        scanf("%d%d",&a,&p);
        exgcd(a,p,x,y);

        if(x)
            printf("%d\n",((LL)x+p)%p); //x可能为负数
        else
            puts("impossible");
    }

    return 0;

}

快速幂求逆元:

算法基础课y总给出的大致证明

快速幂求逆元.png

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

typedef long long LL;

int n,p;

LL qmi(int a,int k,int p)
{
    LL res = 1;
    while(k)
    {
        if(k&1) res = (LL)res*a%p;
        a = a*(LL)a%p;
        k>>=1;
    }
    return res;
}
int main()
{
    cin>>n;

    while(n--)
    {
        int a,p;
        scanf("%d%d",&a,&p);
        if(a%p)
            printf("%d\n",qmi(a,p-2,p));
        else
            puts("impossible");
    }

    return 0;
}

递推法:

对于输出一系列的mod p的逆元,我们可以使用递推法

(递推公式 : inv[b] = (p-p/b) * inv[ p % b ] % p)

inv[1] = 1;
for(int i = 2; i<=n ;i++)
{
    inv[i] = (LL)(p-p/i)*inv[p%i]%p;
    printf("%d\n",inv[i]);
}

2 评论


用户头像
yxc   2019-10-15 09:32         踩      回复

图片链接失效了

用户头像
Moon_light   2019-10-15 09:58         踩      回复

😂回去重新上传下hh


App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息