A/B——同余定理+逆元(除法逆元)

同余定理:
数论中的重要概念。给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作 ab ( modm) a ≡ b   (   m o d m ) 。对模m同余是整数的一个等价关系

(a+b ) % c=(a % c+b % c) % c ( a + b   )   %   c = ( a   %   c + b   %   c )   %   c

(a  b) % c=(a % c  b % c) % c ( a   ∗   b )   %   c = ( a   %   c   ∗   b   %   c )   %   c


a=k1m+r1b=k2m+r2 a = k 1 ∗ m + r 1 b = k 2 ∗ m + r 2

(a+b) % m=((k1m+r1)+(k2m+r2)) % m=((k1+k2)m+(r1+r2)) % m=(r1+r2) % m=(a % m+b % m) % m(811)(812)(813)(814) (811) ( a + b )   %   m = ( ( k 1 ∗ m + r 1 ) + ( k 2 ∗ m + r 2 ) )   %   m (812) = ( ( k 1 + k 2 ) ∗ m + ( r 1 + r 2 ) )   %   m (813) = ( r 1 + r 2 )   %   m (814) = ( a   %   m + b   %   m )   %   m

所以

(a+b) % m=(a % m+b % m) ( a + b )   %   m = ( a   %   m + b   %   m )


要求(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


m=9973 m = 9973 那么

AB %;m=AB1 %m=ABBC%m(815)(816) (815) A B   % ; m = A B ∗ 1   % m (816) = A B ∗ B ∗ C % m


BC%m=1 B ∗ C % m = 1

BC1modm B ∗ C ≡ 1 m o d m

所以
CB C 就 是 B 的 逆 元

已知 B B ,可以根据拓展欧几里德算法求得 C C ,所以最终的结果就是
ACmod9973 A ∗ C m o d 9973


由费马小定理可以得出

C=B m2(m=9973) C = B   m − 2 ( m = 9973 )
所以
ans=nB m2%mans=(n%m)(B m2%m)%m() a n s = n ∗ B   m − 2 % m a n s = ( n % m ) ∗ ( B   m − 2 % m ) % m ( 为 了 防 止 数 据 溢 出 )


代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int c=9973;

ll pow_mod(ll a,ll b,ll c)
{
    ll ans=1;
    a%=c;
    while(b)
    {
        if(b&1) ans=ans*a%c;
        a=a*a%c;
        b>>=1;
    }
    return ans;
 } 

ll x,y;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    ll r=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return r;
}


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,b;
        scanf("%d %d",&n,&b);
        printf("%lld\n",(long long) n*(pow_mod(b,c-2,c)%c)%c);//pow_mod(b,c-2,c)就是B的逆元C 

    }
    return 0;
}

你可能感兴趣的:(同余定理+逆元)