例题
hdu1576 A/B http://acm.hdu.edu.cn/showproblem.php?pid=1576
题意:已知n(n = A % 9973) ,A%B=0,gcd(B,9973)=1;
求:(A / B) % 9973
法一 暴力出奇迹
本题没有给A,给了n以及和A的关系,所以这是一个桥梁
n = A % 9973得到A = n + 9973 * k; (A / B) % 9973 = ans 得到 A = B *(ans + y * 9973 ) ;
即 n + 9973 * k = B *(ans + y * 9973 );取余n = B * ans % 9973;
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,b; 4 int t; 5 int main(){ 6 ios::sync_with_stdio(0); 7 cin >> t; 8 while(t--){ 9 cin >> n >> b; 10 n %= 9973;b %= 9973; 11 for(int i = 0; i < 9973; i++){ 12 if(i * b % 9973 == n){ 13 cout << i << endl; 14 break; 15 } 16 } 17 } 18 return 0; 19 }
如果乘法逆元又应该怎么做呢
博客一https://www.cnblogs.com/dupengcheng/p/5487362.html
博客二https://www.cnblogs.com/-citywall123/p/10673212.html
看完这两篇应该懂了
法二 费马小定理
#include <bits/stdc++.h> using namespace std; #define int long long int n,b; int t; int pow(int a,int b,int p){ int ans = 1 & p; for(;b;b >>= 1){ if(b & 1) ans = ans * a % p; a = a * a % p; } return ans; } int niyuan(int a,int p){ return pow(a,p - 2,p); } signed main(){ ios::sync_with_stdio(0); cin >> t; while(t--){ cin >> n >> b; b = niyuan(b,9973); cout << n *b % 9973 << endl; } return 0; }
模板
int pow(int a,int b,int p){ int ans = 1 & p; for(;b;b >>= 1){ if(b & 1) ans = ans * a % p; a = a * a % p; } return ans; } int niyuan(int a,int p){ return pow(a,p - 2,p); }
法三 扩展欧几里德
#include <bits/stdc++.h> using namespace std; #define int long long int n,b; int t; int exgcd(int a,int b,int &x,int &y){ if(!b){ x = 1,y = 0; return a; } int d = exgcd(b,a % b,y,x); y -= x * (a / b); return d; } int niyuan(int a,int b){//求a对b取模的逆元 int x,y; exgcd(a,b,x,y); return (x + b) % b; } signed main(){ ios::sync_with_stdio(0); cin >> t; while(t--){ cin >> n >> b; b = niyuan(b,9973); cout << n *b % 9973 << endl; } return 0; }
模板
1 int exgcd(int a,int b,int &x,int &y){ 2 if(!b){ 3 x = 1,y = 0; 4 return a; 5 } 6 int d = exgcd(b,a % b,y,x); 7 y -= x * (a / b); 8 return d; 9 } 10 int niyuan(int a,int b){//求a对b取模的逆元 11 int x,y; 12 exgcd(a,b,x,y); 13 return (x + b) % b; 14 }