QOJ.ac

QOJ

时间限制: 3 s 内存限制: 1024 MB 总分: 100 可 Hack ✓

#16889. Оптимизация NPU

统计

Furiosa AI разрабатывает NPU (Neural Processing Unit), который позволяет выполнять обучение и вывод моделей искусственного интеллекта быстрее, чем традиционные процессоры. Программы, работающие на обычном процессоре, используют данные, хранящиеся на хосте (host), и обрабатывают их с помощью различных операторов для вычисления нужных значений. В этой задаче мы упростим этот процесс и рассмотрим следующую среду:

  • Хост имеет пространство для хранения $1\,000\,000$ элементов данных, каждое из которых пронумеровано от $0$ до $999\,999$.
  • Каждый оператор принимает один или несколько входных элементов данных и вычисляет один выходной элемент данных. Операторы также пронумерованы числами от $0$ до $999\,999$.
  • Программа выражается с помощью следующей БНФ (формы Бэкуса-Наура):

    <number> ::= 0 | 1 | ... | 999999 <value> ::= <number> | <number>(<list>) <list> ::= <value> | <list>,<value>

  • Программа вычисляет одно значение. То есть программа представляет собой строку, соответствующую <value>.

  • Значение <value> вычисляется следующим образом:
    • Если <value> представлено как <number>, это данные, хранящиеся в ячейке <number> на хосте перед запуском программы.
    • Если <value> представлено как <number>(<list>), это выходные данные, вычисленные с использованием оператора <number>, где в качестве входных данных последовательно используются значения <value> из списка <list>.
  • В одной программе один и тот же <number> не встречается несколько раз.

NPU, разрабатываемый Furiosa AI, может выполнять ту же программу быстрее, чем обычный процессор, но для этого требуется компилятор, который переводит программу в низкоуровневые инструкции, используемые NPU. Поскольку объем используемой памяти и время выполнения программы зависят от того, как она скомпилирована, для эффективного использования NPU необходим оптимизированный компилятор.

NPU имеет память, способную хранить $M$ элементов данных, где каждая ячейка памяти пронумерована от $0$ до $M-1$. NPU поддерживает три типа инструкций:

  • a >> b
    • Копирует данные из ячейки a хоста в ячейку b памяти NPU. ($0 \le a < 1\,000\,000$; $0 \le b < M$). Если данные уже существуют, они перезаписываются.
  • a << b
    • Копирует данные из ячейки b памяти NPU в ячейку a хоста. ($0 \le a < 1\,000\,000$; $0 \le b < M$). Если данные уже существуют, они перезаписываются.
  • o = w | m1 m2 ... ml
    • Вычисляет выходные данные оператора w, используя значения из адресов памяти $m_1, m_2, \dots, m_l$ в качестве входных данных, и сохраняет результат в ячейке o памяти NPU.
    • Ячейка, в которую сохраняются выходные данные, должна отличаться от ячеек, в которых хранятся входные данные. То есть $o \neq m_i$ ($1 \le i \le l$).

Программа для NPU представляет собой последовательность вышеуказанных инструкций, которые выполняются по порядку.

Хотя эффективность программы определяется множеством факторов, программа, использующая минимальное количество инструкций, с высокой вероятностью будет эффективной. Дана строка, соответствующая <value>. Преобразуйте её в программу для NPU, которая вычисляет значение <value> и сохраняет его в ячейке памяти $0$, используя минимально возможное количество инструкций.

Входные данные

В первой строке задается размер памяти NPU $M$ ($1 \le M \le 1\,000\,000$). Во второй строке задается строка, соответствующая <value>, которую необходимо вычислить. Длина этой строки не превышает $1\,000\,000$.

Выходные данные

Если NPU не хватает памяти для компиляции программы, выведите $-1$. Если программу можно скомпилировать, в первой строке выведите минимальное количество инструкций, необходимых для вычисления <value>. Начиная со следующей строки, выведите инструкции, составляющие программу, по одной в строке в порядке их выполнения. Все токены в одной инструкции должны быть разделены пробелами. Если существует несколько вариантов ответа, выведите любой из них.

Примеры

Пример 1

7
71(72(41,42),73(43,44))
7
41 >> 3
42 >> 4
43 >> 5
44 >> 6
1 = 72 | 3 4
2 = 73 | 5 6
0 = 71 | 1 2

Пример 2

3
71(72(41,42),73(43,44))
9
43 >> 2
44 >> 0
1 = 73 | 2 0
59 << 1
41 >> 2
42 >> 0
1 = 72 | 2 0
59 >> 2
0 = 71 | 1 2

Пример 3

2
71(72(41,42),73(43,44))
-1

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.