B. Козак Вус i програмування#8752

B. Козак Вус i програмування

1 секунда
64 мегабайти
Легка

У Козака є улюблений робот на ім'я Atlas, з яким він багато грався у дитинстві. Нещодавно Вус зрозумів, що ніколи не намагався програмувати робота на різні задачі, тож почав читати інструкцію. Він дізнався, що Atlas має регістрів, кожен з яких пронумерований, починаючи з , і кожен регістр містить біти. Це означає, що кожен регістр складається з нулів та одиниць.

Вус дізнався, що робота можна програмувати за допомогою семи спеціальних команд, які виконують операції з цими регістрами. Для простоти будемо називати регістр регістром з номером , а a_i — числом, що зберігається у -му регістрі.

  1. setValue(, ) — Замінює вміст регістра на вміст регістра . Кожен біт у регістрі замінюється відповідним бітом з регістра , що еквівалентно виконанню операції a_i = a_j.

  2. setXor(, , ) — Замінює вміст регістра на поразрядне XOR регістрів і . Кожен біт регістра замінюється XOR відповідних бітів регістрів і .

  3. setAnd(, , ) — Замінює вміст регістра на поразрядне AND регістрів і .

  4. setOr(, , ) — Замінює вміст регістра на поразрядне OR регістрів і .

  5. shiftLeft(, ) — Зсуває всі біти у регістрі на позицій вліво. (Детальніше нижче.)

  6. shiftRight(, ) — Зсуває всі біти у регістрі на позицій вправо. (Детальніше нижче.)

  7. setNot(, ) — Замінює вміст регістра на поразрядне NOT регістра . Кожен біт регістра встановлюється у , якщо відповідний біт у регістрі дорівнює , і у , якщо він дорівнює .

Поразрядний XOR двох бітів дає , якщо вони однакові, і , якщо вони різні.

Поразрядний AND двох бітів дає лише якщо обидва біти дорівнюють , і інакше.

Поразрядний OR двох бітів дає , якщо хоча б один біт — , і лише якщо обидва біти — .

Зсув вліво на позицій у регістрі означає, що кожен біт зміщується на позицій вліво: значення на позиції стає значенням на позиції i - x, заповнюючи нулями, якщо i-x виходить за межі. Така ж логіка і для зсуву вправо, заповнюються нулі зліва.

Після прочитання інструкції Козак Вус вигадав шість цікавих задач. Він зрозумів, що для програмування робота на певну задачу потрібно ввести лише послідовність команд, яка вирішить її. Нехай — кількість команд, виконаних для певної задачі.

Ось задачі:

Підзадача 1: (до балів) Число збережено у регістрі . Усі інші регістри заповнені нулями. Нехай число дорівнює , якщо парне, і , якщо непарне. Потрібно, щоб після виконання операцій число було записане у регістрі .

Підзадача 2: (до балів) У регістрі збережено число , у регістрі — число . Усі інші регістри заповнені нулями. Нехай z = x + y. Потрібно, щоб після виконання операцій число було записане у регістрі . Якщо для представлення у двійковому вигляді потрібно більше бітів, у регістрі мають зберігатися лише перші біти.

Підзадача 3: (до балів) У регістрі збережено число . Нехай — кількість одиниць у двійковому записі числа . Після виконання операцій має бути записане у регістрі .

Підзадача 4: (до балів) У регістрах та збережено різні числа та відповідно. Якщо x > y, то a = 0, b = 1; якщо y > x, то b = 0, a = 1. Потрібно, щоб після виконання операцій числа та були записані у регістри та відповідно.

Підзадача 5: (до балів) У регістрі збережено число . Нехай — кількість одиниць у двійковому записі числа . Після виконання операцій у регістрі має бути записане число 2^y - 1.

Підзадача 6: (до балів) Нехай — масив, що містить різних невід'ємних цілих чисел. Для кожного від до число a_i збережено у -му регістрі. Нехай — відсортований (за зростанням) масив із . Після виконання операцій для кожного від до число b_i має бути записане у -му регістрі. Індекси у масивах і — від .

Якщо початкове значення регістра не вказане, на початку він заповнюється нулями. Усі числа знаходяться у межах від до 2^{64} - 1.

Козак Вус знає кількість команд, необхідних для розв'язання кожної підзадачі, але не знає, які саме команди слід застосувати, тож просить твоєї допомоги. Твоя задача — знайти послідовність команд, яка вирішить відповідну задачу для будь-яких вхідних даних.

Зверни увагу, що дозволено виконати не більше 10^5 команд. Перевищення ліміту призведе до балів та вердикту Wrong Answer. Виконання некоректної команди призведе до балів та вердикту Runtime Error. Результатом твого розв'язання у кожній підзадачі будуть регістри, у яких містяться правильні відповіді. Усі інші регістри можуть містити будь-які числа.

Взаємодія

Для кожної підзадачі потрібно реалізувати окрему функцію:

void solve(int n)

де — номер підзадачі. Ця функція приймає параметр — номер підзадачі — і нічого не повертає.

Ви можете використовувати наступні функції:

  • void setValue(integer , integer )

    • Присвоює значення регістра (1 \le j \le 40) регістру (1 \le i \le 40).

  • void setXor(integer , integer , integer )

    • Присвоює значення операції XOR регістрів і (1 \le j, k \le 40) регістру (1 \le i \le 40).

  • void setAnd(integer , integer , integer )

    • Присвоює значення операції AND регістрів і (1 \le j, k \le 40) регістру (1 \le i \le 40).

  • void setOr(integer , integer , integer )

    • Присвоює значення операції OR регістрів і (1 \le j, k \le 40) регістру (1 \le i \le 40).

  • void shiftLeft(integer , integer )

    • Зсуває регістр (1 \le i \le 40) вліво на позицій (0 \le x \le 64).

  • void shiftRight(integer , integer )

    • Зсуває регістр (1 \le i \le 40) вправо на позицій (0 \le x \le 64).

  • void setNot(integer , integer )

    • Присвоює поразрядне NOT регістра (1 \le j \le 40) регістру (1 \le i \le 40).

Приклади

Припустимо, що число збережено у регістрі , а число — у регістрі . Якщо виконати наступні команди:

setValue(3, 1)setXor(4, 1, 2)setAnd(5, 1, 2)setOr(6, 2, 1)shiftLeft(2, 3)shiftRight(1, 2)setNot(7, 2)

Тоді перші сім чисел у масиві регістрів будуть такими: [1, 24, 6, 5, 2, 7, 18446744073709551591].

Приклад 1

Loading
Loading