codeforces.com/contest/251/problem/C

C. Number Transformation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Little Petya likes positive integers a lot. Recently his mom has presented him a positive integer a. There's only one thing Petya likes more than numbers: playing with little Masha. It turned out that Masha already has a positive integer b. Petya decided to turn his number a into the number b consecutively performing the operations of the following two types:c++

  1. Subtract 1 from his number.
  2. Choose any integer x from 2 to k, inclusive. Then subtract number (a mod x) from his number a. Operation a mod x means taking the remainder from division of number a by number x.

Petya performs one operation per second. Each time he chooses an operation to perform during the current move, no matter what kind of operations he has performed by that moment. In particular, this implies that he can perform the same operation any number of times in a row.ide

Now he wonders in what minimum number of seconds he could transform his number a into number b. Please note that numbers x in the operations of the second type are selected anew each time, independently of each other.ui

Input

The only line contains three integers ab (1 ≤ b ≤ a ≤ 1018) and k (2 ≤ k ≤ 15).this

Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64dspecifier.spa

Output

Print a single integer — the required minimum number of seconds needed to transform number a into number b.code

Examples
input
10 1 4
output
6
input
6 3 10
output
2
input
1000000000000000000 1 3
output
666666666666666667
Note

In the first sample the sequence of numbers that Petya gets as he tries to obtain number b is as follows: 10  →  8  →  6  →  4  →  3  →  2  →  1.orm

In the second sample one of the possible sequences is as follows: 6  →  4  →  3.blog

 題意:three

給出 a b kci

求a變到b的最小步數,每一步能夠選擇兩種變化中的一種:a=a-1和a=a-a%i (2<=i<=k);

代碼:

//k最大隻有15,首先要想到2~15的lcm必然是一個循環節,而後就能夠利用分塊的思想,分紅(a-1)/lcm+1塊,每一塊
//的大小是lcm,而後中間整個塊的能夠計算(每一塊最大不會超過360360),兩邊的剩餘的也能夠計算了。這裏我用的
//記憶化bfs找的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1000009;
int k,vis[MAXN];
int gcd_(int x,int y) { return y==0?x:gcd_(y,x%y); }
int lcm_(int x,int y) { return x/gcd_(x,y)*y; }
ll bfs(ll x,ll y)
{
    queue<ll>q;
    memset(vis,-1,sizeof(vis));
    q.push(x);
    vis[x-y]=0;
    while(!q.empty()){
        ll now=q.front();q.pop();
        if(now==y) return vis[0];
        for(int i=2;i<=k;i++){
            ll xx=now-now%i;
            if(xx<y||vis[xx-y]!=-1) continue;
            vis[xx-y]=vis[now-y]+1;
            q.push(xx);
        }
        ll xx=now-1;
        if(vis[xx-y]!=-1) continue;
        vis[xx-y]=vis[now-y]+1;
        q.push(xx);
    }
}
int main()
{
    ll a,b,ans=0;
    cin>>a>>b>>k;
    if(k==2){
        cout<<a-b<<"\n";
        return 0;
    }
    ll last=2;
    for(int i=3;i<=k;i++) last=lcm_(last,i);
    ll tmp1=a/last;
    ll tmp2=(b-1)/last+1;
    if(tmp1>tmp2) ans=bfs(a,tmp1*last)+(tmp1-tmp2)*bfs(last,0)+bfs(last*tmp2,b);
    else ans=bfs(a,b);
    cout<<ans<<"\n";
    return 0;
}
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息