#P16669. [CSPro 30] 解压缩
[CSPro 30] 解压缩
Background
The testdata on Luogu is only for non-official communication and is not official testdata. Official judging link: https://www.cspro.org/.
Xixi Aifu Island Operations Company is a large enterprise responsible for maintaining and operating the island’s infrastructure. Within the company, many departments in charge of different businesses need to use server facilities. To make management easier and reduce operating costs, the company built a private cloud system. Besides providing hosted virtual machine services, this private cloud system also offers some other services. The most well-received one is the log service. Previously, logs of different business systems were stored separately on their own servers, which was not only inconvenient for viewing and analysis but also had the risk of loss. The log service can collect logs from different business systems in a unified way, making them easier to view and manage.
The logs collected by the log server are plain text and highly structured. This means log data can be compressed very small. However, the amount of log data is huge and efficiency requirements are high, so it is acceptable to sacrifice some compression ratio and use an efficient compression algorithm to compress the log data. Little C is assigned to implement a program to decompress the logs. Given a segment of compressed log data, he needs to decompress it.
Problem Description
The data stream produced by this compression algorithm can be viewed as a sequence of elements. There are two kinds of elements: literals and back-references. A literal contains a sequence of bytes; when decompressing it, output these bytes directly. A back-reference repeats and outputs a part of the data stream that has already been decompressed. A back-reference can be written as , containing two numbers: the offset and the length . The offset indicates how far to look back from the current position, and the length indicates how many bytes need to be output repeatedly. It is required that . If bytes have already been decompressed, then:
- When , it means to output the bytes starting from offset (the first byte has offset ). For example, if the already decompressed data stream is
abcde, then the back-reference means outputcd. - When , it means to first output the bytes starting from offset , then keep outputting these bytes repeatedly until a total of bytes have been output. For example, if the already decompressed data stream is
abcde, then the back-reference means outputdeded.
The compressed data format consists of two parts: the header field and the data field. The header field stores the length of the original data. Let the original data length be . Then can be expressed as , where and . The header field has length bytes, storing in order . That is, each byte uses the lower bits to store . The highest bit is for the last byte, and for all other bytes. For example, if the original data length is , then are , i.e. 0x2C, 0x0A in hexadecimal. Therefore, the header field length is , and the byte sequence is 0xAC 0x0A.
:::align{center}
:::
The data field stores the compressed data, which is a contiguous sequence of elements. The lowest two bits of the first byte of each element indicate the element type.
When the lowest two bits are , it is a literal. If the literal contains bytes and , then the upper bits of the first byte represent . The following bytes are the original bytes contained in the literal. For example, byte 0xE8 is binary 1110 1000. The lowest two bits are , so it is a literal. The upper six bits are 111010, which is , meaning the literal contains bytes. Therefore, the following bytes are the original bytes contained in this literal.
If , then represent in to bytes in little-endian order, and store them after the first byte. When the value stored in the upper six bits of the first byte is , or , it means that is stored using , or bytes, respectively. For example, in the byte sequence 0xF4 0x01 0x0A, the first byte is binary 1111 0100. The lowest two bits are , so it is a literal. The upper bits are 111101, which is , meaning the next two bytes store the literal length. The following two bytes 0x01 0x0A, in little-endian order, form the hexadecimal number 0x0A01, i.e. decimal , meaning this literal contains bytes. The following bytes are the original bytes contained in this literal.
:::align{center}

:::
When the lowest two bits of the first byte are 01, it is a back-reference , with and . Here, takes bits: its lower bits are stored in the following byte, and its upper bits are stored in the upper bits of the first byte. takes bits, stored in bits to of the first byte, as shown below.
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+-----+-----+-+-+ +----------------+
|o(h3)| l-4 |0|1| |o (lower 8 bits)|
+-----+-----+-+-+ +----------------+
For example, bytes 0x2D 0x1A have first byte binary 001 011 01. The lowest two bits are 01, so it is a back-reference. Bits to are 011, which is , meaning , so . The upper bits are 001; together with the following byte 0x1A, they form the hexadecimal number 0x11A, i.e. decimal , meaning . Therefore, this back-reference is .
:::align{center}
:::
When the lowest two bits of the first byte are 10, it is a back-reference , with and . Here, takes bits and is stored in little-endian order in the following two bytes. takes bits and is stored in the upper bits of the first byte. For example, bytes 0x3E 0x1A 0x01 have first byte binary 0011 1110. The lowest two bits are 10, so it is a back-reference. The upper bits are 001111, which is , meaning , so . The following two bytes 0x1A 0x01, in little-endian order, form the hexadecimal number 0x011A, i.e. decimal , meaning . Therefore, this back-reference is .
:::align{center}
:::
We规定 that the lowest two bits of an element’s first byte are not allowed to be 11. If this happens, then the data field is invalid.
The compressed data is valid if and only if all of the following conditions are satisfied.
- The header field length does not exceed bytes.
- The header field can be correctly restored to the original data length.
- The lowest two bits of the first byte of each element are not
11. - Each element can be restored to the original data according to the rules.
- The obtained original data length is exactly equal to the original data length encoded in the header field.
Input Format
Read input from standard input.
The input contains multiple lines. The first line is a positive integer , indicating the number of bytes of the compressed data to be decompressed.
Next, there are lines describing the compressed data. Each line contains only digits or letters a to f. Every two characters form a hexadecimal number representing one byte. Except for the last line, each line contains exactly bytes. The input data is guaranteed to be valid.
Output Format
Write output to standard output.
Output the decompressed data. Output consecutive bytes per line, and each byte is represented by two hexadecimal digits (digits or letters a to f). The last line may contain fewer than bytes.
81
8001240102030405
060708090af03c00
0102030405060708
090a0b0c0d0e0f01
0203040506070809
0a0b0c0d0e0f0102
030405060708090a
0b0c0d0e0f010203
0405060708090a0b
0c0d0e0fc603000d
78
0102030405060708
090a000102030405
060708090a0b0c0d
0e0f010203040506
0708090a0b0c0d0e
0f01020304050607
08090a0b0c0d0e0f
0102030405060708
090a0b0c0d0e0f0d
0e0f0d0e0f0d0e0f
0d0e0f0d0e0f0d0e
0f0d0e0f0d0e0f0d
0e0f0d0e0f0d0e0f
0d0e0f0d0e0f0d0e
0f0d0e0f0d0e0f0d
0e02030405060708
Hint
Explanation for Sample 1
The above input data can be reorganized as.
80 01
24 0102030405060708090a
f0 3c
000102030405060708090a0b0c0d0e0f
0102030405060708090a0b0c0d0e0f
0102030405060708090a0b0c0d0e0f
0102030405060708090a0b0c0d0e0f
c6 0300
0d 78
First read the first byte 80. Its highest bit is , so continue reading the second byte 01. Its highest bit is , so reading the header field ends. We get , and the original data length is.
Then continue reading byte 24, whose binary is 0010 0100. The lowest two bits are 00, so it is a literal. Taking its upper six bits gives decimal , meaning the length of this literal is . Then read bytes to get the literal 0102030405060708090a.
Then continue reading byte f0, whose binary is 1111 0000. The lowest two bits are 00, so it is a literal. Taking its upper six bits gives decimal , meaning the next one byte is the literal length minus . Continue reading byte 3c to get the number , meaning this literal has length , and then read bytes.
Then continue reading byte c6, whose binary is 1100 0110. The lowest two bits are 10, so it is a back-reference. Taking its upper six bits gives decimal , meaning the back-reference length is . Then read two bytes 03 00, which in little-endian order form the hexadecimal number 0x0003, i.e. decimal , meaning the back-reference offset is . Therefore, this back-reference is . Since , repeat the last three bytes in the buffer 0d 0e 0f for times, then output 0d 0e to make a total of bytes.
Then continue reading byte 0d, whose binary is 0000 1101. The lowest two bits are 01, so it is a back-reference. Take bits to , which are 011, i.e. decimal , meaning the back-reference length is . Then read one byte 78, whose binary is 0111 1000. Combine it with the top three bits 000 of this element’s first byte 0d to get 000 0111 1000, which is decimal , meaning the back-reference offset is . Therefore, this back-reference is . Previously, bytes have been output. Now output bytes starting from position with offset from the beginning of the buffer, i.e. 02030405060708.
At this point, the input has been fully processed. A total of bytes have been output, consistent with the original data length read from the header field, so decompression succeeds.
Subtasks
- For of the input, the decompressed data length does not exceed bytes, and contains only literals, and the length of data in each literal element does not exceed bytes.
- For of the input, the decompressed data length does not exceed bytes, and contains only literals, and the length of data in each literal element does not exceed bytes.
- For of the input, the decompressed data length does not exceed bytes, and contains only literals.
- For of the input, the decompressed data length does not exceed bytes, and all back-references have first bytes whose lowest two bits are
01. - For of the input, the decompressed data length does not exceed bytes.
- For of the input, the decompressed data length does not exceed ( bytes), and , and the data is guaranteed to be valid compressed data.
Translated by ChatGPT 5