扩展欧几里德

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.youkuaiyun.com/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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值