#P8523. [IOI 2021] 位移寄存器

[IOI 2021] 位移寄存器

Background

Abusing the judging system for this problem will result in an account ban.

Due to technical limitations, please do not submit this problem using C++ 14 (GCC 9).

This is an interactive problem. You only need to implement the function required in the code.

Your code does not need to include any extra header files, and you do not need to implement the main function.

At the beginning of your code, you need to add the following code:

#include<vector>
void append_move(int t, int y);
void append_store(int t, std::vector<bool> v);
void append_and(int t, int x, int y);
void append_or(int t, int x, int y);
void append_xor(int t, int x, int y);
void append_not(int t, int x);
void append_left(int t, int x, int p);
void append_right(int t, int x, int p);
void append_add(int t, int x, int y);
void append_print(int t);

Problem Description

Engineer Christopher is developing a new computer processor.

This processor can access mm different bb-bit storage units (in this problem, m=100m = 100 and b=2000b = 2000). They are called registers, indexed from 00 to m1m - 1. We denote these registers as r[0],r[1],,r[m1]r[0], r[1], \ldots , r[m - 1]. Each register is an array of bb bits, indexed from 00 (the rightmost bit) to b1b - 1 (the leftmost bit). For all ii (0im10 \le i \le m - 1) and jj (0jb10 \le j \le b - 1), we denote the jj-th bit of register ii as r[i][j]r[i][j].

For any bit sequence d0,d1,,dl1d_0, d_1, \ldots , d_{l - 1} (of some length ll), its integer value is $2^0 \cdot d_0 + 2^1 \cdot d_1 + \cdots + 2^{l - 1} \cdot d_{l - 1}$. We say the integer stored in a register is the integer value of the bit sequence in the register, i.e., it is $2^0 \cdot r[i][0] + 2^1 \cdot r[i][1] + \cdots + 2^{b - 1} \cdot r[i][b - 1]$.

The processor has 99 types of instructions that can be used to modify the bits in registers. Each instruction operates on one or more registers and stores its output into one of the registers. Below, we use x:=yx := y to denote an operation that changes the value of xx to become yy. The operations of each instruction type are described as follows.

move(t,y)\operatorname{\mathit{move}}(t, y): Copy the bit array in register yy to register tt. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=r[y][j]r[t][j] := r[y][j].

store(t,v)\operatorname{\mathit{store}}(t, v): Set register tt to vv, where vv is a bb-bit array. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=v[j]r[t][j] := v[j].

and(t,x,y)\operatorname{\mathit{and}}(t, x, y): Compute the bitwise AND of registers xx and yy, and store the result in register tt. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=1r[t][j] := 1 if both r[x][j]r[x][j] and r[y][j]r[y][j] are 11, otherwise set r[t][j]:=0r[t][j] := 0.

or(t,x,y)\operatorname{\mathit{or}}(t, x, y): Compute the bitwise OR of registers xx and yy, and store the result in register tt. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=1r[t][j] := 1 if at least one of r[x][j]r[x][j] and r[y][j]r[y][j] is 11, otherwise set r[t][j]:=0r[t][j] := 0.

xor(t,x,y)\operatorname{\mathit{xor}}(t, x, y): Compute the bitwise XOR of registers xx and yy, and store the result in register tt. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=1r[t][j] := 1 if exactly one of r[x][j]r[x][j] and r[y][j]r[y][j] is 11, otherwise set r[t][j]:=0r[t][j] := 0.

not(t,x)\operatorname{\mathit{not}}(t, x): Compute the bitwise NOT of register xx, and store the result in register tt. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=1r[x][j]r[t][j] := 1 - r[x][j].

left(t,x,p)\operatorname{\mathit{left}}(t, x, p): Shift all bits in register xx left by pp positions, and store the result in register tt. The result of shifting register xx left by pp is a bb-bit array vv. For all jj (0jb10 \le j \le b - 1), if jpj \ge p then v[j]=r[x][jp]v[j] = r[x][j - p], otherwise v[j]=0v[j] = 0. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=v[j]r[t][j] := v[j].

right(t,x,p)\operatorname{\mathit{right}}(t, x, p): Shift all bits in register xx right by pp positions, and store the result in register tt. The result of shifting register xx right by pp is a bb-bit array vv. For all jj (0jb10 \le j \le b - 1), if jb1pj \le b - 1 - p then v[j]=r[x][j+p]v[j] = r[x][j + p], otherwise v[j]=0v[j] = 0. For all jj (0jb10 \le j \le b - 1), set r[t][j]:=v[j]r[t][j] := v[j].

add(t,x,y)\operatorname{\mathit{add}}(t, x, y): Add the integer values in registers xx and yy, and store the result in register tt. The addition is done modulo 2b2^b. More formally, let XX be the integer value in register xx before the operation, and YY be the integer value in register yy before the operation. Let TT be the integer value in register tt after the operation. If X+Y<2bX + Y < 2^b, set the bits in tt so that T=X+YT = X + Y. Otherwise, set the bits in tt so that T=X+Y2bT = X + Y - 2^b.

Christopher wants you to solve two tasks using this new processor. The task type is given by an integer ss. For all task types, you need to create a program that is a sequence of the instructions defined above.

The program input consists of nn integers a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1], and each integer has kk bits, i.e., a[i]<2ka[i] < 2^k (0in10 \le i \le n - 1). Before the program is executed, all input numbers are stored in register 00 in order, so that for all ii (0in10 \le i \le n - 1), the integer value of the kk-bit sequence $r[0][i \cdot k], r[0][i \cdot k + 1], \ldots , r[0][(i + 1) \cdot k - 1]$ equals a[i]a[i]. Note that nkbn \cdot k \le b. All other bits in register 00 (with indices between nkn \cdot k and b1b - 1, inclusive), as well as all bits in all other registers, are initialized to 00.

Executing a program means executing its instructions in order. After the last instruction is executed, the program output is computed from the final values of the bits in register 00. Specifically, the output is a sequence of nn integers c[0],c[1],,c[n1]c[0], c[1], \ldots , c[n - 1], where for each ii (0in10 \le i \le n - 1), c[i]c[i] is the integer value of the sequence of bits in register 00 from iki \cdot k to (i+1)k1(i + 1) \cdot k - 1. Note that after the program finishes, the remaining bits in register 00 (with indices at least nkn \cdot k), as well as all bits in other registers, may have arbitrary values.

The first task (s=0s = 0) is to find the minimum among the input integers a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1]. Specifically, c[0]c[0] must be the minimum of a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1]. The values of c[1],c[2],,c[n1]c[1], c[2], \ldots , c[n - 1] can be arbitrary.

The second task (s=1s = 1) is to sort the input integers a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1] in non-decreasing order. Specifically, for all ii (0in10 \le i \le n - 1), c[i]c[i] should equal the (1+i)(1 + i)-th smallest integer among a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1] (that is, c[0]c[0] is the smallest input integer).

Please help Christopher write programs to solve these tasks. Each program may contain at most qq instructions.

Input Format

You need to implement the following function:

void construct_instructions(int s, int n, int k, int q)
  • ss: the task type.
  • nn: the number of integers in the input.
  • kk: the number of bits in each input integer.
  • qq: the maximum allowed number of instructions.

This function will be called exactly once, and it should create a sequence of instructions for the required task.

This function should call one or more of the following functions to create the instruction sequence:

void append_move(int t, int y)
void append_store(int t, std::vector<bool> v)
void append_and(int t, int x, int y)
void append_or(int t, int x, int y)
void append_xor(int t, int x, int y)
void append_not(int t, int x)
void append_left(int t, int x, int p)
void append_right(int t, int x, int p)
void append_add(int t, int x, int y)
  • Each function appends one instruction move(t,y)\operatorname{\mathit{move}}(t, y), store(t,v)\operatorname{\mathit{store}}(t, v), and(t,x,y)\operatorname{\mathit{and}}(t, x, y), or(t,x,y)\operatorname{\mathit{or}}(t, x, y), xor(t,x,y)\operatorname{\mathit{xor}}(t, x, y), not(t,x)\operatorname{\mathit{not}}(t, x), left(t,x,p)\operatorname{\mathit{left}}(t, x, p), right(t,x,p)\operatorname{\mathit{right}}(t, x, p), or add(t,x,y)\operatorname{\mathit{add}}(t, x, y), respectively.
  • For all relevant instructions, tt, xx, and yy must be at least 00 and at most m1m - 1.
  • For all relevant instructions, tt, xx, and yy do not have to be pairwise distinct.
  • For the left and right instructions, pp must be at least 00 and at most bb.
  • For the store instruction, the length of vv must be bb.

You may also call the following function to help test your solution:

void append_print(int t)
  • When judging your solution, all calls to this function will be ignored.
  • In the sample evaluator, this function appends a print(t)\operatorname{\mathit{print}}(t) operation to the program.
  • When the sample evaluator executes a program and encounters a print(t)\operatorname{\mathit{print}}(t) operation, it prints the nn kk-bit integers formed by the first nkn \cdot k bits of register tt.
  • tt must satisfy 0tm10 \le t \le m - 1.
  • Any call to this function will not be counted in the number of instructions you create.

After appending the last instruction, construct_instructions should return. Then, the program you created will be judged on a number of test cases, where each test case provides input data consisting of nn kk-bit integers a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1]. If the output c[0],c[1],,c[n1]c[0], c[1], \ldots , c[n - 1] produced by your program for the given input data satisfies the following conditions, your solution will be considered accepted for that test case:

  • If s=0s = 0, c[0]c[0] should be the minimum of a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1].
  • If s=1s = 1, for all ii (0in10 \le i \le n - 1), c[i]c[i] should be the (1+i)(1 + i)-th smallest integer among a[0],a[1],,a[n1]a[0], a[1], \ldots , a[n - 1].

When judging your solution, one of the following error messages may be given:

  • Invalid index: the register index given as tt, xx, or yy in some function call is invalid (possibly negative).
  • Value to store is not b bits long: the length of vv provided to append_store is not equal to bb.
  • Invalid shift value: the value of pp provided to append_left or append_right is not between 00 and bb (inclusive).
  • Too many instructions: your function attempts to append more than qq instructions.
0 2 1 1000
0 0
0 1
1 0
1 1
-1
move 1 0
right 1 1 1
and 0 0 1
0
0
0
1
1 2 1 1000
0 0
0 1
1 0
1 1
-1

move 1 0
right 1 1 1
and 2 0 1
or 3 0 1
left 3 3 1
or 0 2 3
0 0
0 1
0 1
1 1

Hint

For all testdata:

  • m=100m = 100.
  • b=2000b = 2000.
  • 0s10 \le s \le 1.
  • 2n1002 \le n \le 100.
  • 1k101 \le k \le 10.
  • q4000q \le 4000.
  • 0a[i]2k10 \le a[i] \le 2^k - 1 (for all 0in10 \le i \le n - 1).
Subtasks Score Special constraints
11 1010 s=0s = 0, n=2n = 2, k2k \le 2, q=1000q = 1000.
22 1111 s=0s = 0, n=2n = 2, k2k \le 2, q=20q = 20.
33 1212 s=0s = 0, q=4000q = 4000.
44 2525 s=0s = 0, q=150q = 150.
55 1313 s=1s = 1, n10n \le 10, q=4000q = 4000.
66 2929 s=1s = 1, q=4000q = 4000.

Thanks to

https://www.luogu.com.cn/user/676498
ing the interactive library. The interactive library in the attachment can be used for local testing, and it is different from the interactive library used in the actual judging.

Translated by ChatGPT 5