【hdu1576】A/B——扩展欧几里得算法

扩展欧几里得的模板题,要记住:

x=y1;

y=x1-a/b*y1。

这道题的推导过程如下:

1.因为A/B==0,所以令A/B=x,即A=Bx。又因为n=A%m,所以m*y+n=A。

由上面可推导出Bx-my=n。

2.由扩展欧几里得算法可以算出B*x1+m*y1=1的根,等式两边同时乘上n可以变形为B*(x1*n)-m*(-n*y1)=n。

所以x=n*x1。到这里我们只需要通过扩欧算出x1,答案即为(x1*n)%m。

3.最后要注意的一点,扩展欧几里得算法算出的x1可能为负数,这显然是不成立的。又因为

x=x1+b*t;

y=y1-a*t;

所以x1的值可以写成(x%m+m)%m。这样的话负数也转成了正数,就可以输出答案啦!

具体细节看代码:

#include<cstdio>
const int m=9973;
using namespace std;
void e_gcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;y=0;return;
    }
    e_gcd(b,a%b,x,y);
    int t=y;
    y=x-a/b*y;
    x=t;
}
int main()
{
    int t,n,b,x,y;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&b);
        e_gcd(b,m,x,y);
        x=(x%m+m)%m;
        printf("%d\n",x*n%m);
    }
    return 0;
}

hdu1576

时间: 2025-01-02 17:54:26

【hdu1576】A/B——扩展欧几里得算法的相关文章

扩展欧几里得算法详解

一:欧几里得算法(辗转相除法) 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a = kb +r 因此d也是(a,b)的公约数 因此(a

扩展欧几里得算法的模板实现

我居然现在还记不住扩欧的板子,我太弱啦! 扩展欧几里得算法解决的是这样的问题: 给定一个不定方程组ax+by=gcd(a,b),求他的一组整数解 先给出实现代码 void exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0;//gcd(a,0)显然等于1*a-0*0=a return a; } int ans=exgcd(b,a%b,x,y); int tem=x; x=y; y-=tem-(a/b)*y; return ans;} 但实

欧几里得算法与扩展欧几里得算法_C++

先感谢参考文献:http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html 注:以下讨论的数均为整数 一.欧几里得算法(重点是证明,对后续知识有用) 欧几里得算法,也叫辗转相除,简称 gcd,用于计算两个整数的最大公约数 定义 gcd(a,b) 为整数 a 与 b 的最大公约数 引理:gcd(a,b)=gcd(b,a%b) 证明: 设 r=a%b , c=gcd(a,b) 则 a=xc , b=yc , 其中x , y互质

POJ - 1061 青蛙的约会 (扩展欧几里得算法)

Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面. 我们把这

[NOI2002] 荒岛野人 扩展欧几里得算法

[问题描述] 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,-,M.岛上住着N个野人,一开始依次住在山洞 C1,C2,-,CN中,以后每年,第i个野人会沿顺时针向前走Pi个洞住下来.每个野人i有一个寿命值Li,即生存的年数.下面四幅图描述了一个有6个 山洞,住有三个野人的岛上前四年的情况.三个野人初始的洞穴编号依次为1,2,3:每年要走过的洞穴数依次为3,7,2:寿命值依次为4,3,1.     奇怪的是,虽然野人有很多,但没有任何两个野人在有生之年处在同一个

扩展欧几里得算法(extgcd)

相信大家对欧几里得算法,即辗转相除法不陌生吧. 代码如下: int gcd(int a, int b){ return !b ? gcd(b, a % b) : a; } 而扩展欧几里得算法,顾名思义就是对欧几里得算法的扩展. 切入正题: 首先我们来看一个问题: 求整数x, y使得ax + by = 1, 如果gcd(a, b) != 1, 我们很容易发现原方程是无解的.则方程ax + by = 1有正整数对解(x, y)的必要条件是gcd(a, b) = 1,即a, b 互质. 此时正整数对解

欧几里得算法以及扩展欧几里得算法(过河noip2005提高组第二题)

欧几里得算法:也被称作辗转相除法 gcd(a,b)=gcd(b,a%b); 终止条件a=gcd b=0; (gcd为a,b的最大公约数) 扩展欧几里得算法: a 和 b 的最大公约数是 gcd ,一定能够找到这样的 x 和 y ,使得: a*x + b*y = gcd 成立 我们只需要找到特殊解x0,y0; 则通解为 x = x0 + (b/gcd)*t    y = y0 – (a/gcd)*t 那如何求出下一组解呢 仿照欧几里得算法a=b,b=a%b代入. a%b = a - (a/b)*b

扩展欧几里得算法学习记

话说以前我刷noip题的时候就想学这个东西了,结果却一直拖到了现在…… 到了高二才会这种东西的我实在是个蒟蒻啊! 将扩展欧几里得算法之前,先讲讲欧几里得算法是什么:gcd(a,b)=gcd(b,a%b).很显然是不?但我们还是要给出证明(设r=a%b): 设x是a,b的一个公约数,由于存在k使得a=k*b+r,又由于a|x,b|x,则有r|x,所以x是b,r的公约数 设x是b,r的一个公约数,因为存在k使得a=k*b+r,且b|x,r|x,那么a|x,所以x是a,b的公约数 综上所述,a和b的所

HDU - 1576 A/B(扩展欧几里得算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 题意:要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1). 普通版欧几里得算法(辗转相除): 1 typedef long long LL; 2 LL gcd(LL a,LL b){ 3 return (b==0) ? a : gcd(b,a%b); 4 } 扩展欧几里得算法(理论):对于不完全为0的非负整数,