QOJ.ac

QOJ

Total points: 100 Communication Unavailable

#5366. Supercomputing in Mianyang

Statistics

Mianhuang has $n$ computers, and these $n$ computers are all connected to each other using special cables. They are numbered $0 \dots n-1$.

There are two $n \times n$ matrices $A[0\dots n-1, 0\dots n-1]$ and $B[0\dots n-1, 0\dots n-1]$, where each element is a 32-bit unsigned integer. You need to use these computers to calculate the matrix $C=AB$. You only need to calculate the result of each element in $C$ modulo $2^{32}$.

Initially, the $i$-th computer only knows the values of the $i$-th row of $A$ and the $i$-th row of $B$. You need to have them perform some calculations so that, in the end, the $i$-th computer knows the values of the $i$-th row of $C$. You need to have these computers communicate to complete the calculation.

Communication is conducted in rounds. Specifically, at the beginning of each round, for each $i$, the $i$-th computer decides on an array $\{\mathrm{sendTo}_{i,j}, 0 \leq j < n\}$ based on the information it knows, representing what information the $i$-th computer will send to the $j$-th computer in this round. Once all computers have finished their decisions, all $\mathrm{sendTo}_{i,j}$ are instantly transmitted to their target computers. After the transmission is complete, the $n$ computers enter the next round of communication. (Note: Unlike the practice contest problem, the information sent by the same computer to other computers does not have to be the same.)

Because the cables are very special, the bandwidth is quite limited (actually, it's because Mianhuang allocated too little budget). Therefore, in each round of communication, $\mathrm{sendTo}_{i,j}$ can only transmit 32 bits. That is to say, $\mathrm{sendTo}_{i,j}$ must be a 32-bit unsigned integer between $0$ and $2^{32}-1$.

At the same time, the disk size of each computer is also very limited (also due to the low budget), and it can only store $4 \times 10^4$ 32-bit binary numbers.

Now you need to design a reasonable algorithm so that in as few rounds as possible (the budget is too low to pay the electricity bill), each computer can calculate what it needs to calculate.


The above is the background of the problem. Due to the limitations of the evaluation system, we will simulate the communication process through some means. The simulation method is described below.

In this problem, you need to implement the function:

void node_mul(int maxSize, int node_id, int round_id);

where node_id represents the ID of the current computer, and round_id represents the current round of communication, with communication rounds starting from 1.

Next, we use uint to represent a 32-bit unsigned integer.

We have set up a global variable CO, and your code needs to interact with it to complete the calculation.

CO records the information transmitted during the entire communication process, the information initially obtained by each computer, and the storage system of each computer. We organize the $4 \times 10^4$ 32-bit binary numbers stored in the $i$-th computer into an array uint F[i][40000] for us to access.

CO has the following methods that can be called:

  • uint getMemory(int w)
    • Returns F[node_id][w].
  • void updateMemory(int w, uint val)
    • Modifies F[node_id][w] to val.
  • uint getinfoA(int w)
    • Returns A[node_id][w].
  • uint getinfoB(int w)
    • Returns B[node_id][w].
  • uint getinfoT(int k, int w)
    • Gets the message received by the current computer from the $w$-th computer in round $k$, requiring $1 \leq k < \mathrm{round_id}$.
  • void updateC(int w, uint val)
    • Submits val as the answer for C[node_id][w]. You can submit multiple times, but only the last one will be used.
  • void getinfoC(int w)
    • Returns the C[node_id][w] you submitted. If you have not submitted it, it returns $0$.
  • void sendinfoTo(int k, uint w)
    • In this round of communication, this computer will send $w$ to the $k$-th computer. You can call this function multiple times to send to the same computer in the same round, but we only use the last one.

For example, if you call the following in node_mul(5, 2, 2):

CO.sendinfoTo(1, 2);
CO.sendinfoTo(1, 3);

Then we consider that you sent the information $3$ to computer $1$.

The following describes our simulation method.

We will first iterate $i=1 \dots 130$, representing the current communication round, and then inside the loop body, iterate $j=0 \dots n-1$, calling node_mul(matSize, j, i). After that, we check whether all computers have submitted the correct answer, that is, whether for all $x$, the $x$-th computer already knows all elements of the $x$-th row of $C$. If so, the test ends, and we consider that these computers completed the calculation in $i$ rounds. If after 130 rounds of communication, there is still a computer that has not calculated what it should calculate, it is considered to have completed the calculation in 131 rounds of communication.

Below are some code specifications and precautions.

In the node_mul function, any illegal behavior of transmitting information, that is, behavior that does not transmit information through the methods given in the problem, will be considered cheating. This includes but is not limited to: creating global variables; embedding assembly code; using functions like malloc, calloc to allocate memory; sharing memory through new pointers; writing data to the local disk, etc.

At the same time, you are not allowed to call any functions other than the methods of CO, and you cannot define any global variables, including static global variables.

In addition, if you pass illegal parameters when calling CO's methods (such as getMemory(-1), sendinfoTo(114514, 35)), the simulator will enter an infinite loop and cause your code to time out.

Furthermore, since we use a code-filling mechanism, you can only fill in the implementation of the node_mul function in the code blanks and cannot perform illegal operations, including but not limited to: ending the node_mul function early and declaring other functions, etc.

Finally, some attempts to modify memory are also illegal. You cannot modify the value of every global variable we define, such as modifying every variable inside the CO type body.

We will manually check whether your code uses illegal behavior. If we believe your code has illegal behavior (including but not limited to the behaviors mentioned above), we will reject your submission, change your submission score to 0, and notify you. Since manual inspection has a certain delay, please try to avoid submitting dangerous code a few minutes before the end of the competition, otherwise, it may lead to you only knowing that the submission was rejected after the competition ends.

However, you can declare some local variables and arrays within the function body to help you complete the calculation.

You can view the see.cpp we provided to understand other details, but see.cpp is not the code we use for final testing; the final test code will be encrypted. During the final test, we will insert your code into see.cpp and run it. If see.cpp runs for more than 50 seconds, your problem will be considered timed out.

When submitting, please submit the code inside the function body. If you complete it as void node_mul(int matSize, int node_id, int round_id){int yjq;}, you should only submit "int yjq;".

Note that when testing see.cpp locally, you need to increase the stack size.

Constraints

This problem has only one test case with $n = 125$.

Assuming you spend $x$ rounds to complete the calculation, your final score is:

$$f(x) = \begin{cases} 0 & x \geq 126 \\ 100 & x \leq 34 \\ \max\left(20, \min\left(100, \left\lfloor60 + 10 \times \ln\left(\frac{y}{1-y}\right)\right\rfloor \right)\right) & \text{otherwise}\end{cases}$$

where $y=\displaystyle \frac{80-x}{92}+0.5$, and this division is not rounded.


or upload files one by one:

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.