【寒假】HDU 1576(扩展欧几里得算法)

本文深入解析了在特定模数下求解(A/B)%M问题的算法思路,利用扩展欧几里得算法高效求解模逆元,解决大数除法的余数问题。通过实例讲解了如何将复杂数学问题转化为可编程实现的算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
Output
对应每组数据输出(A/B)%9973。
Sample Input
2
1000 53
87 123456789
Sample Output
7922
6060

问题分析:设(A/B)%9973 = K, 则A/B = k + 9973x (x未知), 因此A = kB + 9973xB,

又A%9973 = n, 所以kB%9973 = n, 故kB = n + 9973y (y未知)

故(k/n)B +(-y/n)*9973 = gcd(B,9973)=1

扩展欧几里得 求出k/n, 再乘以个n,记得取模,就是answer了

然后就来到扩展欧几里得算法了,这里引用百度:

求解 x,y的方法的理解
设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,a>b>0 时
设 ax1+ by1= gcd(a,b);
bx2+ (a mod b)y2= gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则:ax1+ by1= bx2+ (a mod b)y2;
即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
说明: a-[a/b]*b即为mod运算。[a/b]代表取小于a/b的最大整数。
也就是ax1+ by1 == ay2+ b(x2- [a / b] *y2);
根据恒等定理得:x1=y2; y1=x2- [a / b] *y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。

#include <stdio.h>
#include <stdlib.h>
 
#define m 9973
 
void Extend_gcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1,y=0;
        return ;
    }
    Extend_gcd(b,a%b,x,y);
    int r=x;
    x=y;
    y=r-(a/b)*y;
}
 
int main()
{
    int n,b,t,x,y;
    scanf("%d",&t);
 
    while(t--)
    {
        scanf("%d%d",&n,&b);
        Extend_gcd(b,m,x,y);
        x=(x%m+m)%m;//x可能为负,需调整
        printf("%d\n",(x*n)%m);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值