HDUOJ 1576.A/B
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10675 Accepted Submission(s): 8542
Problem Description
要求(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
Author
xhd
Source
HDU 2007-1 Programming Contest
这道题看上去很简单,其实还是蛮难的。很考验数学的能力,这里给出两种做法。
做法一:
要求的设为 x=
A
B
\frac{A}{B}
BAmod 9973,则可知
A
B
\frac{A}{B}
BA=9973 *
k
1
k_1
k1 + x。
又有A mod 9973=n。
则可以设A=9973 *
k
1
k_1
k1 * B + x * B=
k
2
k_2
k2 * 9973 + n。
可知 9973 *
k
1
k_1
k1 * B + x * B - n=
k
2
k_2
k2 * 9973。
两边同时 mod 9973 可知(x * B - n) mod 9973 =0;
不难看出B 和 n是已知的,x有0 <= x <= 9972,则可以枚举x的值以得出答案。
附上Ac代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,b;
cin>>n>>b;
for(int i=0;i<9973;i++)
{
if(((((b%9973)*i)%9973-n)%9973)==0)
{
cout<<i<<endl;
break;
}
}
}
return 0;
}
做法二:
第二种方法则要引入逆元的思想。
因为要求的是 x =
A
B
\frac{A}{B}
BAmod 9973,可以写作x = (A *
B
−
1
{B}^{-1}
B−1) mod 9973。(其中
B
−
1
{B}^{-1}
B−1是B关于模9973的乘法逆元)
把括号去掉:x = (A mod 9973 *
B
−
1
{B}^{-1}
B−1 mod 9973) mod 9973。
化简:x = (n *
B
−
1
{B}^{-1}
B−1 mod 9973)mod 9973。
已知gcd(B,9973)=1,又知道9973是一个质数,那么久可以直接使用费马小定理去求
B
−
1
{B}^{-1}
B−1的值。
*费马小定理:假如p是质数,且gcd(a,p)=1,那么
a
p
−
1
{a}^{p-1}
ap−1≡1(mod p)。
B
9973
−
1
{B}^{9973-1}
B9973−1≡1(mod 9973)。
可以写成B *
B
9971
{B}^{9971}
B9971≡1(mod 9973)。
又因为
B
−
1
{B}^{-1}
B−1是B关于模9973的乘法逆元,则B *
B
−
1
{B}^{-1}
B−1≡1(mod 9973)。
可得
B
−
1
{B}^{-1}
B−1=
B
9971
{B}^{9971}
B9971。
带入前面的化简式中,可知:x = (n *
B
9971
{B}^{9971}
B9971 mod 9973)mod 9973。
B
9971
{B}^{9971}
B9971 mod 9973可以使用快速幂算出,再带入式子,便可以直接算出结果x。
附上Ac代码:
#include <iostream>
#include <algorithm>
using namespace std;
int ksm(int a,int b,int mod)
{
int r=1,c=a%mod;
while(b)
{
if(b%2)
r=(r*c)%mod;
c=(c*c)%mod;
b=b/2;
}
return r;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n,b;
cin>>n>>b;
cout<<(n*ksm(b,9971,9973))%9973<<endl;
}
}