Explanation
To transform into , we proceed greedily. If , it can be shown that it is never optimal to add more than once consecutively before dividing by 2. To see this, consider adding two times before the division. While this leads to three operations in sum, we can instead first divide and then just add one, which has the same effect but requires only two operations.
Then, if , as the optimality of the strategy above is already shown, let's reuse it and work on by allowing multiplication, division, and subtraction by one. We therefore either divide by two (and first subtract by one if is odd) or subtract times to directly reach . One can see that these operations applied on are equivalent to what one does on in reversed order.
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;using ll = long long;ll solve(ll a, ll b) {if (a == b) {return 0;} else if (a > b) {/*
Java
import java.io.*;import java.util.*;public class Soulmates {public static long solve(long a, long b) {if (a == b) {return 0;} else if (a > b) {/** Divide a greedily until a <= b, add 1 in case a is odd to enable
Python
def solve(a, b):if a == b:return 0elif a > b:"""Divide a greedily until a <= b, add 1 in case a is odd to enabledivision."""is_odd = a % 2return 1 + is_odd + solve((a + is_odd) // 2, b)
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!