0
点赞
收藏
分享

微信扫一扫

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


同余定理:
数论中的重要概念。给定一个正整数m,如果两个整数a和b满足a-b能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b ( 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=k1∗m+r1b=k2∗m+r2 a = k 1 ∗ m + r 1 b = k 2 ∗ m + r 2


(a+b) % m=((k1∗m+r1)+(k2∗m+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=AB∗1 %m=AB∗B∗C%m(815)(816) (815) A B   % ; m = A B ∗ 1   % m (816) = A B ∗ B ∗ C % m




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


B∗C≡1modm B ∗ C ≡ 1 m o d m


所以


C就是B的逆元 C 就 是 B 的 逆 元


已知

B B ,可以根据拓展欧几里德算法求得 C C ,所以最终的结果就是

A∗Cmod9973 A ∗ C m o d 9973

由费马小定理可以得出

C=B m−2(m=9973) C = B   m − 2 ( m = 9973 )

所以

ans=n∗B m−2%mans=(n%m)∗(B m−2%m)%m(为了防止数据溢出) a n s = n ∗ B   m − 2 % m a n s = ( n % m ) ∗ ( B   m − 2 % m ) % m ( 为 了 防 止 数 据 溢 出 )

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#include<map>
#include<set>
#include<vector>
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;
}


举报

相关推荐

0 条评论