This question a $ exgcd $
How to look is $ exgcd $
Consider the $ exgcd $ how to do this problem
Consider $ wx + dy = p $ solution is obtained, and to try to meet $ x + y + z = n $
Then the solution is to ask a group of $ x, y $ $ x + y $ such as small
Because $ d <w $, so for $ wx + dy = p $
When the time taken $ Y $ of the smallest positive integer solutions $ x + y $ must be minimal
You can then be determined using the minimum $ exgcd $ $ y $, Y $ and then obtained by $ X $ $
Then $ \ text {Wrong answer on test 5} $ ....
After the end of the game found explosive $ lnog \ long $ a
The finer is required wording, when obtaining a set $ x, y $ satisfying $ wx + dy = gcd (w, d) $ after
We can not directly $ y = y * (p / gcd (w, d)) $ then $ mod = w / gcd (w, d), y = (y \% mod + mod) \% mod $
But should direct $ mod = w / gcd (w, d), y = ((y \% mod * (p / gcd (w, d)) \% mod) \% mod + mod) \% mod $
Since then $ w, d <= 10 ^ 5 $, it will not burst
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } ll n,p,w,d; ll exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1,y=0; return a; } ll g=exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; return g; } int main() { n=read(),p=read(),w=read(),d=read(); ll x,y,g=exgcd(w,d,x,y); if(p%g) { printf("-1\n"); return 0; } ll mo=w/g; y=((y%mo)*((p/g)%mo)%mo+mo)%mo; x=(p-y*d)/w; if((x+y>n) || (x<0)) printf("-1\n"); else printf("%lld %lld %lld\n",x,y,n-x-y); return 0; }
In fact because $ w, d <= 10 ^ 5 $, we can enumerate violence from small to large $ y \ in [0, w) $ and determine whether there is a legitimate $ x $
Once that is found there is a minimum of $ y $
Noting determination equation is $ p-dy = 0 \ mod w $, noted $ p-dy \ circular mod w $ segment length is also less than $ $ W
So if the enumeration finished $ y \ in [0, w) $ later still no solution then it must be no solution
Because $ w <= 10 ^ 5 $ , so to force, from the code: jiangly
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); LL n, p, d, w; cin >> n >> p >> d >> w; LL y = 0; while (y < d && (p - w * y) % d != 0) ++y; if (y < d) { LL x = (p - w * y) / d; LL z = n - x - y; if (x >= 0 && z >= 0) cout << x << " " << y << " " << z << "\n"; else cout << "-1\n"; } else cout << "-1\n"; return 0; }