扩展欧几里德

Ax+By = c。当且仅当c为gcd(A, B)的倍数时有解。

扩展gcd,不仅求出gcd而且求出解x,y。常用于求解ax≡1(mod m) => ax+by=1。

递归实现,结束状态时x=1,y=0。更新x和y:x=y1, y = x1-(a/b)*y1。

51Nod1352 https://vjudge.net/contest/218366#problem/C

中间溢出要用long long

Ax+By=N-1参考:https://blog.csdn.net/Viscu/article/details/52735003

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<vector>
 8 #include<stack>
 9 #include<queue>
10 #define lson l, m, rt<<1
11 #define rson m+1, r, rt<<1|1
12 #define IO ios::sync_with_stdio(false);cin.tie(0);
13 #define INF 0x3f3f3f3f
14 #define MAXN 100010
15 const int MOD=1e9+7;
16 typedef long long ll;
17 using namespace std;
18 ll n, a, b, t, x, y, cnt;
19 ll ext_gcd(ll a, ll b, ll &x, ll &y)
20 {
21     if(b == 0){
22         x = 1;
23         y = 0;
24         return a;
25     }
26     ll ans = ext_gcd(b, a%b, x, y);
27     ll t = x;
28     x = y;
29     y = t-a/b*y;
30     return ans;
31 }
32 int main()
33 {
34     cin >> t;
35     while(t--){
36         cnt=0;
37         cin >> n >> a >> b;
38         ll r = ext_gcd(a, b, x, y); 
39         if((n+1)%r!=0){//无解 
40             cout << "0" << endl; 
41         } 
42         else{
43             ll mod = b/r, mini, lcm = a*b/r;//lcm = a*b/gcd, 再除a就是mod 
44             mini = (x*(n+1)/r%mod+mod)%mod;//mini为最小非负x 
45             if(mini == 0){//0不能为除数,且给定集合不含0 
46                 mini = mod;
47             }
48             if(mini*a>n){//如果一开始就大了 
49                 cout << "0" << endl;
50             }
51             else cout << (n-a*mini)/lcm+1 << endl;//因为每次都转移lcm 
52         }
53     }
54     return 0;
55 }
原文地址:https://www.cnblogs.com/Surprisezang/p/8669152.html