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 }