大意: 给定$a,b$, $1le a,ble 1e12$, 定义
$f(a,0)=0$
$f(a,b)=1+f(a,b-gcd(a,b))$
求$f(a,b)$.
观察可以发现, 每次$b$一定是减去若干个相同的$gcd$, 并且每次减的$gcd$一定是递增的, 并且一定是在$gcd$最接近$b$的时候开始减, 可以预处理出所有这样的位置, 然后模拟.
#include <iostream> #include <cstdio> #include <math.h> #include <queue> #define REP(i,a,n) for(int i=a;i<=n;++i) #define pb push_back using namespace std; typedef long long ll; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll x,y; vector<ll> fac, q; int main() { cin>>x>>y; int mx = sqrt(x+0.5); REP(i,1,mx) if (x%i==0) { fac.pb(i); if (x/i!=i) fac.pb(x/i); } for (ll t:fac) q.pb(y/t*t); sort(q.begin(),q.end(),greater<ll>()); q.erase(unique(q.begin(),q.end()),q.end()); q.erase(q.begin()),q.pb(0); ll now = y, ans = 0; for (ll t:q) { ll g = gcd(x,now); if ((now-t)%g==0) { ans += (now-t)/g; now = t; } } cout<<ans<<endl; }