Arrival 2, 3 ... k least common multiple for LCM
When x reaches a multiple of the LCM, X can only be reduced by one
From A to B, it's going to be a multiple of LCM.
We will divide A, b by LCM
So the minimum number of complete LCM segments is the same, so we just need to calculate the minimum value of a LCM segment multiplied by the number of complete LCM segments
And the end of the incomplete LCM segment and that is the answer
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace Std;
const int MAXN = 1000010;
int VIS[MAXN];
struct node
{
__int64 step;
__int64 value;
};
int gcd (int a, int b)
{
if (a < b)
Swap (A, b);
if (b = = 0)
return A;
return gcd (b, a%b);
}
int LCM (int a,int b)
{
Return A*B/GCD (A, b);
}
Queue<struct node>que;
__int64 BFS (__int64 N, __int64 K, __int64 en)
{
while (Que.size ()) Que.pop ();
struct node first = {0,n};
Que.push (first);
Vis[n] = 1;
memset (Vis, 0, sizeof (VIS));
while (Que.size ())
{
struct node now = Que.front ();
Que.pop ();
if ((__int64) Now.value = = en)
return now.step;
for (int i = 1;i <= k;i++)
{
__int64 T;
if (i = = 1) t = now.value-1;
else T = now.value-now.value%i;
if (t<0 | | vis[t]) continue;
struct node next = {now.step+1, t};
Que.push (next);
Vis[t] = 1;
}
}
return 0;
}
int main ()
{
Freopen ("Input.txt", "R", stdin);
__int64 A, B, K;
while (~SCANF ("%i64d%i64d%i64d", &a, &b, &k))
{
int sum= 2;
if (k = = 2)
{
printf ("%i64d\n", A-B);
Continue;
}
for (int i = 3;i <= k;i++)
sum = LCM (sum, i);
__int64 first = (b + (__int64) sum-1)/(__int64) sum;
__int64 last = A/(__int64) sum;
__int64 ans;
if (last >= first)
{
ans= (Last-first) * (BFS ((sum-1), K, 0) + 1);
Ans + = BFS (sum,k,b%sum);
Ans + = BFS (a%sum,k,0);
}
else ans = BFS (a%sum, K, b%sum);
printf ("%i64d\n", ans);
}
}
Codeforces Round #153 (Div. 1) C number transformation BFS