【扩展欧几里得】hdu 1576 A/B
2017-10-05 19:12
477 查看
A/B
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 639 Accepted Submission(s): 517
[align=left]Problem Description[/align]
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
[align=left]Input[/align]
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
[align=left]Output[/align]
对应每组数据输出(A/B)%9973。
[align=left]Sample Input[/align]
2 1000 53 87 123456789
[align=left]Sample Output[/align]
7922 6060
逆元解法:
#include<stdio.h> #define MOD 9973 //****************************** //返回d=gcd(a,b);和对应于等式ax+by=d中的x,y long long extend_gcd(long long a,long long b,long long &x,long long &y) { if(a==0&&b==0) return -1;//无最大公约数 if(b==0){x=1;y=0;return a;} long long d=extend_gcd(b,a%b,y,x); y-=a/b*x; return d; } //*********求逆元素******************* //ax = 1(mod n) long long mod_reverse(long long a,long long n) { long long x,y; long long d=extend_gcd(a,n,x,y); if(d==1) return (x%n+n)%n; else return -1; } int main() { int T; int n,B; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&B); int x=mod_reverse(B,MOD); printf("%d\n",n*x%MOD); } return 0; }
扩展欧几里得求ax+by=c解法:
先设(A/B)%9973 = k
--->> A/B = k + 9973 * x
--->> A = kB + 9973*x*B
--->> kB % 9973 = n
--->> 则kB = n + 9973 * y
--->> 则 kB + 9973 *y = n,y属于整数,可正可负
--->>(k / n) * B + 9973*(y / n) = 1
--->> 又gcd(B,9973)= 1
--->> 所以求出k = x *n %9973
#include <iostream> #include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <bitset> #include <string> #include <vector> #include <iomanip> #include <cstring> #include <algorithm> #include <functional> #define PI acos(-1) #define eps 1e-8 #define inf 0x3f3f3f3f #define debug(x) cout<<"---"<<x<<"---"<<endl typedef long long ll; using namespace std; ///求ax+by=gcd(a,b)的特解x0,y0以及gcd(a,b) long long exgcd(long long a, long long b, long long &x, long long &y) { if (b == 0) { x = 1; y = 0; return a; } long long ans = exgcd(b, a % b, x, y); long long temp = x; x = y; y = temp - (a / b) * y; return ans; ///ans=gcd(a,b); } ///求ax=c(mod b),即求ax+by=c的最小非负整数解 long long cal(long long a, long long b, long long c) { long long x, y; long long gcd = exgcd(a, b, x, y); if (c % gcd != 0) { return -1; } x = x * (c / gcd); int t = b / gcd; if (t < 0) { t = -t; } long long ans = x % t; if (ans <= 0) { ans += t; } return ans; } int main() { long long t, n, b; cin >> t; while (t--) { cin >> n >> b; long long ans = cal(b, 9973, 1); cout << ans*n % 9973 << endl; } return 0; } ///求ax+by=c的特解: ///x0=x0*(c/gcd); ///y0=y0*(c/gcd); ///求通解: ///x=x0+(b/gcd)*k; ///y=y0-(a/gcd)*k; /************************************************ ┆ ┏┓ ┏┓ ┆ ┆┏┛┻━━━┛┻┓ ┆ ┆┃ ┃ ┆ ┆┃ ━ ┃ ┆ ┆┃ ┳┛ ┗┳ ┃ ┆ ┆┃ ┃ ┆ ┆┃ ┻ ┃ ┆ ┆┗━┓ ┏━┛ ┆ ┆ ┃ ┃ ┆ ┆ ┃ ┗━━━┓ ┆ ┆ ┃ AC代马 ┣┓┆ ┆ ┃ ┏┛┆ ┆ ┗┓┓┏━┳┓┏┛ ┆ ┆ ┃┫┫ ┃┫┫ ┆ ┆ ┗┻┛ ┗┻┛ ┆ ************************************************ */
相关文章推荐
- 扩展欧几里得,逆元初识(poj 1061+codeforce 7C line+hdu 1576 A/B)
- 【A/B%m+扩展欧几里得】hdu 1576 A/B
- HDU1576 A/B (扩展欧几里得求逆元)
- hdu 1576 A/B (求乘法逆元——扩展欧几里得)
- HDU 1576 A/B (扩展欧几里得应用)
- HDU 1576 A/B 扩展欧几里得
- HDU 1576 A/B(扩展欧几里得,思维)
- hdu 1576A/B(扩展欧几里得)
- HDU 1576 A/B (逆元求扩展欧几里得)
- hdu1576 A/B 扩展欧几里得求逆元
- hdu_1576_包含数学变形的扩展欧几里得
- hdu_1576A/B(扩展欧几里得求逆元)
- hdu 1576 A/B(扩展欧几里得)
- HDU 1576 A/B (扩展欧几里得)
- HDU 1576 扩展欧几里得
- HDU 1576 A/B 扩展欧几里得
- hdu 1576 扩展欧几里得
- HDU 1576 A/B(欧几里得扩展)
- hdu 1576 A/B(扩展欧几里得)
- HDU - 1576 A/B 扩展欧几里得