HDU 1576 (乘法逆元)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1576

题目大意:求(A/B)mod 9973。但是给出的A是mod形式n,n=A%9973。

解题思路

两种思路,一种从乘法逆元角度,另一种从扩展GCD推公式角度。

①乘法逆元:

先来看下逆元和乘法逆元的关系,对于A*X=B,有X=A-1*B,A-1就是普通的逆元了,在这里就是倒数。

如果A*X=B mod n,变成同余式了,那么A-1依然是存在的,只不过不是倒数了,一般把同余之后的逆元称为乘法逆元。( - -。好像这个定义是错的)。

题目如果是(A/B) mod 9973, 那就简单了。关键A同余化了,所以B也要同余化,这时候就有把B逆运算(除变乘),从普通变成同余状态的乘法逆元运算mod_reverse(B,9973)。

这样A的同余状态a=n,B的同余状态b=mod_reverse(B,9973)。

那么题目直接转化成(a*b)mod 9973 了。

#include "cstdio"
#define LL long long
LL ex_gcd(LL a,LL b,LL &x,LL &y)
{
    if(a==0&&b==0) return -1;
    if(b==0) {x=1;y=0;return a;}
    LL d=ex_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
LL mod_reverse(LL a,LL n)
{
    LL x,y,d=ex_gcd(a,n,x,y);
    if(d==1) return (x%n+n)%n;
    else return -1;
}
int main()
{
    LL T,n,B;
    scanf("%I64d",&T);
    while(T--)
    {
        scanf("%I64d%I64d",&n,&B);
        LL x=mod_reverse(B,9973);
        printf("%I64d\n",(n*x)%9973);
    }
}

②扩展GCD角度:

设A=9973*y+n,因为A%B=0,所以(9973*y+n)=B*x,其中x=A/B

移项,有B*x+9973*(-y)=n。

联想到扩展GCD的式子:B*X+9973*Y=1,两边都乘以n,B*(nX)+9973*(nY)=n。

这样x=nX,y=-nY,只要求出X和Y就行了,套扩展GCD模板即可。

注意这里扩展GCD求出的一组x和y可能都是负值,如果x%9973是错的,对负数取模的方法是(x%mod+mod)%mod.

#include "cstdio"
#define LL long long
LL ex_gcd(LL a,LL b,LL &x,LL &y)
{
    if(a==0&&b==0) return -1;
    if(b==0) {x=1;y=0;return a;}
    LL d=ex_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main()
{
    LL T,n,B;
    scanf("%I64d",&T);
    while(T--)
    {
        scanf("%I64d%I64d",&n,&B);
        LL x,y;
        ex_gcd(B,9973,x,y);
        x*=n;
        printf("%I64d\n",(x%9973+9973)%9973);
    }
}
12168956 2014-11-13 00:56:37 Accepted 1576 0MS 228K 519B C++ Physcal

 

时间: 2024-07-30 10:54:25

HDU 1576 (乘法逆元)的相关文章

hdu 1576 求逆元

题意:给出n=A mod 9973和B,求(A/B) mod 9973 昨天用扩展欧几里得做过这题,其实用逆元也可以做. 逆元的定义:例如a*b≡1 (mod m),则b就是a关于m的逆元. 求逆元方法也很简单,用扩展欧几里得解这个方程即可. 逆元性质:若a是b的逆元,则(x/a)mod p=(x*b)mod p 对于本题呢?设B的逆元为x, 那么有(A/B) mod 9973=((A mod 9973)*(x mod 9973))mod 9973 Reference:  http://blog

HDU 1576 -- A/B (总结乘法逆元的几种求法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7264    Accepted Submission(s): 5774 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%99

HDU 1452 (约数和+乘法逆元)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1452 题目大意:求2004^X所有约数和,结果mod 29. 解题思路: ①整数唯一分解定理: 一个整数A一定能被分成:A=(P1^K1)*(P2^K2)*(P3^K3).....*(Pn^Kn)的形式.其中Pn为素数. 如2004=(22)*3*167. 那么2004x=(22x)*(3x)*(167x). ②约数和公式 对于一个已经被分解的整数A=(P1^K1)*(P2^K2)*(P3^K3)

hdu 1452 Happy 2004 (快速幂+取模乘法逆元)

Problem Description Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004^X. Your job is to determine S modulo 29 (the rest of the division of S by 29).Take X = 1 for an example. The positive integer divisors of

HDU 4828 Grids(卡特兰数+乘法逆元)

首先我按着我的理解说一下它为什么是卡特兰数,首先卡特兰数有一个很典型的应用就是求1~N个自然数出栈情况的种类数.而这里正好就对应了这种情况.我们要满足题目中给的条件,数字应该是从小到大放置的,1肯定在左上角,所以1入栈,这时候我们放2,如果我们把2放在了1的下面就代表了1出栈,把2放在上面就代表了2也进栈(可以看一下hint中第二组样例提示),以此类推,这样去放数,正好就对应了上面一行入栈,下面一行出栈的情况,一共n行,对应上限为n的卡特兰数. 需要注意的地方就是在使用卡特兰数递推式的时候,除法

HDU 1576 A/B (扩展欧几里得应用)

题目链接:HDU 1576 A/B 中文题, 思路:设X=(A/B)%9973.A/B=k_1*9973+X.A=B*k_1*9973+x*B.n=A%9973,A=k_2*9973+n.k_2*9973+n=B*k_1*9973+x*B B*X ≡ n mod 9973 就是转化为 求B关于n模9973 的逆元.gcd(B,9973) = 1 得知一定有解. AC代码: #include<stdio.h> #define ll __int64 ll exgcd(ll a,ll b,ll &a

HDU3037 Saving Beans(Lucas定理+乘法逆元)

题目大概问小于等于m个的物品放到n个地方有几种方法. 即解这个n元一次方程的非负整数解的个数$x_1+x_2+x_3+\dots+x_n=y$,其中0<=y<=m. 这个方程的非负整数解个数是个经典问题,可以+1转化正整数解的个数用插板法解决:$C_{y+n-1}^{n-1}=C_{y+n-1}^y$. 而0<=y<=m,最后的结果就是—— $$\sum_{i=0}^m C_{i+n-1}^i$$ $$C_{n-1}^0+C_{n}^1+C_{n+1}^2+\dots+C_{n-1

UVa 11174 (乘法逆元) Stand in a Line

题意: 有n个人排队,要求每个人不能排在自己父亲的前面(如果有的话),求所有的排队方案数模1e9+7的值. 分析: <训练指南>上分析得挺清楚的,把公式贴一下吧: 设f(i)为以i为根节点的子树的排列方法,s(i)表示以i为根的子树的节点总数. f(i) = f(c1)f(c2)...f(ck)×(s(i)-1)!/(s(c1)!s(c2)!...s(ck)!) 按照书上最开始举的例子,其实这个式子也不难理解,就是先给这些子树确定一下位置,即有重元素的全排列. 子树的位置确定好以后,然后再确定

LightOJ - 1050 (唯一分解+推公式+乘法逆元)

题意:求a^b的所有约数和对1e9+7取模的结果 思路:对于一个数p,进行唯一分解,则p=P1^M1*P2^M2*...*Pn^Mn,则p的所有约数之和等于(P1^0+P1^1+...+P1^M1)*(P2^0+P2^1+...+P2^M2)*...*(Pn^0+Pn^1+...+Pn^Mn), p^t=P1^(M1*t)*P2^(M2*t)*...*Pn^(Mn*t),每一个(Pn^0+Pn^1+...+Pn^Mn)利用等比数列可以直接推出公式为(Pn^(Mn*t+1)-1)/(Pn-1),用