Algorithm Analysis
Let the function compute the number of natural numbers in the interval [1; ] that are divisible by either or . This count equals
Let be the sought -th number. Then must be the smallest natural number such that . We will search for it using binary search, starting with the interval [; ] = [1; ]. Let = ( + ) / 2. If , then the search should continue on the interval [; ], otherwise – on the interval [ + 1; ].
Example
Consider the first example, where , . It is necessary to find the smallest , for which . Let's calculate some values:
The smallest solution to the equation will be .
Algorithm Implementation
Functions for computing GCD and LCM.
long long gcd(long long a, long long b) { return (b == 0) ? a : gcd(b, a % b); } long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
The function returns the number of natural numbers not greater than that are divisible by either or .
long long f(long long n) { return n / a + n / b - n / lcm(a, b); }
Read the input data.
scanf("%lld %lld %lld", &a, &b, &n);
Start the binary search. Look for the smallest value of , for which .
left = 1; right = 1e9; while (left < right) { middle = (left + right) / 2; if (f(middle) >= n) right = middle; else left = middle + 1; }
Print the answer.
printf("%lld\n", left);
Java Implementation
import java.util.*; import java.io.*; public class Main { static long gcd(long a, long b) { return (b == 0) ? a : gcd(b, a % b); } static long lcm(long a, long b) { return a / gcd(a, b) * b; } static long f(long n, long a, long b) { return n / a + n / b - n / lcm(a, b); } public static void main(String[] args) { FastScanner con = new FastScanner(new InputStreamReader(System.in)); long a = con.nextInt(); long b = con.nextInt(); long n = con.nextInt(); long left = 1, right = 1000000000; while (left < right) { long middle = (left + right) / 2; if (f(middle, a, b) >= n) right = middle; else left = middle + 1; } System.out.println(left); } } class FastScanner { private BufferedReader br; private StringTokenizer st; public FastScanner(InputStreamReader reader) { br = new BufferedReader(reader); } public String next() { while (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(br.readLine()); } catch (Exception e) { e.printStackTrace(); } } return st.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } public void close() throws Exception { br.close(); } }