nq1s788

X-магическая пара

Nov 2nd, 2025
626
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.18 KB | None | 0 0
  1. Решение этой задачи основано на алгоритме нахождения GCD.
  2.  
  3. Сначала давайте попытаемся решить ее наивно. Будем поддерживать условие, что 𝑎>𝑏
  4. . Если это не так, давайте поменяем 𝑎
  5.  и 𝑏
  6.  местами. Для начала, если 𝑏>𝑎−𝑏
  7. , давайте присвоим 𝑏:=𝑎−𝑏
  8. . Окей, теперь давайте вычитать 𝑏
  9.  из 𝑎
  10.  до тех пор, пока не выполнится 𝑏≥𝑎−𝑏
  11. , а затем будем повторять этот алгоритм, пока не станет 𝑎=0
  12.  или 𝑏=0
  13. . Если после какого-то шага мы получим 𝑎=𝑥
  14.  или 𝑏=𝑥
  15. , то мы закончили и ответ равен YES. Если 𝑎=0
  16.  или 𝑏=0
  17. , а мы не получили 𝑥
  18. , то ответ равен NO.
  19.  
  20. Окей, мы можем заметить, что мы всегда вычитаем минимально возможное 𝑏
  21.  из 𝑎
  22.  и пытаемся поддерживать это условие. Можно доказать, что такой алгоритм получает все возможные числа, которые в принципе могут быть получены любой последовательностью операций из условия задачи (либо в 𝑎
  23. , либо в 𝑏
  24. ).
  25.  
  26. Теперь нам необходимо каким-то образом ускорить это решение. Очевидно, большинство операций бесполезны для нас в этой конкретной задаче. Первая часть заключается в том, что мы можем пропускать все операции до тех пор, пока 𝑏
  27.  не станет больше, чем 𝑎−𝑏
  28. . Количество таких операций равно ⌊𝑎−𝑏2𝑏⌋
  29. . А вторая часть заключается в том, что мы можем пропускать все операции до тех пор, пока мы не получим 𝑥
  30.  в 𝑎
  31. . Количество таких операций равно ⌊𝑎−𝑥𝑏⌋
  32. . Для простоты эту часть можно также записать как ⌊𝑎−𝑥2𝑏⌋
  33. . Это не особо замедлит наше решение, но формула для финального количества операций, которые мы пропускаем, станет немного проще. Это количество равно 𝑐𝑛𝑡=𝑚𝑎𝑥(1,⌊𝑎−𝑚𝑎𝑥(𝑏,𝑥)2𝑏⌋)
  34.  (фактически, мы берем минимум из тех двух величин, которые мы описали выше, потому что мы не хотим пропустить ни один из этих случаев). Таким образом, мы преобразуем пару (𝑎,𝑏)
  35.  в пару (𝑎−𝑏∗𝑐𝑛𝑡,𝑏)
  36.  и продолжаем этот алгоритм.
  37.  
  38. Также существуют более простые подходы, использующие эту же идею в более красивом виде.
  39.  
  40. Асимптотика решения: 𝑂(log𝑎)
  41.  на набор тестовых данных.
  42.  
  43. #include <bits/stdc++.h>
  44.  
  45. using namespace std;
  46.  
  47. bool get(long long a, long long b, long long x) {
  48.     if (a == x || b == x) return true;
  49.     if (a < b) swap(a, b);
  50.     if (b > a - b) b = a - b;
  51.     if (x > max(a, b) || a == 0 || b == 0) return false;
  52.     long long cnt = max(1ll, (a - max(x, b)) / (2 * b));
  53.     return get(a - b * cnt, b, x);
  54. }
  55.  
  56. int main() {
  57. #ifdef _DEBUG
  58.     freopen("input.txt", "r", stdin);
  59. //  freopen("output.txt", "w", stdout);
  60. #endif
  61.    
  62.     int t;
  63.     cin >> t;
  64.     while (t--) {
  65.         long long a, b, x;
  66.         cin >> a >> b >> x;
  67.         if (get(a, b, x)) {
  68.             cout << "YES" << endl;
  69.         } else {
  70.             cout << "NO" << endl;
  71.         }
  72.     }
  73.    
  74.     return 0;
  75. }
Advertisement
Add Comment
Please, Sign In to add comment