hdu1576-A/B-(同余定理+乘法逆元+费马小定理+快速幂)

A/B

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10383    Accepted Submission(s): 8302


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
 
逆元概念:p是素数,在%p的情况下,如果 ( a*inv(a) ) ≡ 1 (%p),则inv(a)是a的乘法逆元
解题过程:
(A/B)%P
= (A%P) * (1/B)%P 同余定理,并且(A%P)=n,已知
= n * (1/B)%P
先不管n,
 
只看(1/B)%P
找B的逆元,按概念就是  (  B*inv(B) ) % P = 1%P = 1;
代入1/B )%P
=( B*inv(B)/B )%P
=inv(B) %P
 
费马小定理概念:如果p是素数,a和p互质,即gcd(a,p)=1,则 a^(p-1)≡1( %p )
逆元和费马小定理联立可得 a * a^(p-2) ≡ 1( %p ), inv(a) = a^(p-2)
代入inv(B) %P
=B^(P-2) %P
 
则原式 = n * B^(P-2) % P
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const ll p=9973;

ll power(ll a,ll b)//快速幂
{
    ll res=1;
    while(b)
    {
        if(b%2==1)
            res=res*a%p;
        b=b/2;
        a=a*a%p;
    }
    return res%p;
}

int main()
{
    ll t,n,b;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&b);
        ll ans;
        ans=n*power(b,p-2)%p;
        printf("%lld
",ans);
    }
    return 0;
}
 
 
 
原文地址:https://www.cnblogs.com/shoulinniao/p/10358910.html