Условие
В сосуде водяных часов изначально v миллилитров воды. В моменты a, 2a, 3a, … поступает по 1 миллилитру; в моменты b, 2b, 3b, … вытекает по 1 миллилитру. Одновременные поступление и вытекание не меняют объём. Найдите объём через n секунд, включая события в момент n. Гарантируется, что исходной воды хватит на все вытекания даже без поступлений.
Входные данные
В одной строке четыре целых числа v, a, b, n: 0 ≤ v, n ≤ 10^18; 1 ≤ a, b ≤ 10^18.
Что вывести
Выведите одно целое число — ответ на задачу.
Как понимать условие
Числа a и b задают интервалы между событиями, а n — момент, до которого работают часы. При v = 10, a = 2, b = 3, n = 6 вода поступит в секунды 2, 4 и 6, вытечет — в секунды 3 и 6. Получится 10 + 3 − 2 = 11 миллилитров. В шестую секунду происходят оба события, и их общий вклад равен нулю.
Как посчитать события без секундомера
При n = 10^18 цикл по секундам не закончится за отведённое время. Для a = 3 и n = 11 поступления происходят в моменты 3, 6 и 9. Их три: столько же даёт целая часть 11 / 3.
Число поступлений равно n // a, число вытеканий — n // b. Ответ: v + n // a − n // b. Момент n учитывается автоматически: если n делится на a, соответствующее поступление входит в частное.
Проверьте рассуждение
При v = 8, a = 3, b = 4 и n = 12 сколько воды останется?
Почему совпадающие события можно считать отдельно
В момент, кратный и a, и b, в сумму прибавляется 1 и из неё вычитается 1. Общий вклад равен нулю. Искать наименьшее общее кратное не требуется. Гарантия в условии позволяет не моделировать пустой сосуд.
В C++ используйте long long: объём может достигать 2·10^18. В Python целые не ограничены 64 битами. Числа нельзя переводить в float: около 10^18 он уже не различает соседние целые. Время и дополнительная память — O(1).
Проверьте границы
При n = 0 ответ равен v. При a = b объём не меняется. Если событие происходит ровно в момент n, его нужно учесть. Частые ошибки: цикл до n, обычное деление вместо целого и исключение последней секунды.
Реализация на Python
v, a, b, n = map(int, input().split())
print(v + n // a - n // b)
Реализация на C++17
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
long long v, a, b, n; cin >> v >> a >> b >> n;
cout << v + n / a - n / b << "\n";
}