注意:本学期 CS101 PA 的所有 C++ 代码都采用 C++20 标准。如果您使用 GCC 或 Clang,您需要在编译时设置 -std=c++20
。
如果您看到类似这样的报错
1 | g++-9: error: unrecognized command line option ‘-std=c++20’; did you mean ‘-std=c++2a’? |
说明您的编译器版本过低,请安装更高版本的编译器。目前 GCC 13 几乎已经将 C++20 除 modules 外的全部新特性实现完毕,我们推荐使用 GCC 13。
Problem 1. Multiplication of polynomials
In this problem, you are required to implement the multiplication of polynomials.
Formally, let and be two polynomials
Let be their product, i.e. where
Given the coefficients and , your task is to compute .
Input format
On the first line, two positive integers and , separated by a space.
On the second line, integers , separated by spaces.
On the third line, integers , separated by spaces.
Output format
One line, consisting of integers , separated by a space.
Testing on OJ
There are 20 testcases on OJ. For the first 10 testcases, your program (assuming it is named foo.cc
) is compiled with
1 | g++ foo.cc -o foo -std=c++20 -Wall -Wpedantic -Wextra -Werror -DONLINE_JUDGE -fmax-errors=3 -fdiagnostics-color=always -fsanitize=undefined -fsanitize=address -g |
For testcases 11 ~ 20, your program is compiled with
1 | g++ foo.cc -o foo -std=c++20 -Wall -Wpedantic -Wextra -Werror -DONLINE_JUDGE -fmax-errors=3 -fdiagnostics-color=always -O2 |
Due to the OJ settings, there is no way of running a single testcase in pretest (运行自测). You can enter your input data there and see the output. For pretesting, the program will be compiled with the same command as for the first 10 testcases.
This OJ does not support testing of multithreaded programs. The time cost will be the sum of the time cost of each thread.
Data constraints
- .
- for every and .
Hint
It is possible that and are zero, but it does not matter. Just treat them as a normal coefficient.
Anything from the C++20 standard library is allowed. Do not waste your effort on manual memory management unless you really want to pursue extremely high efficiency. Simple arrays and std::vector
are enough for passing all the tests. Do not reinvent wheels like std::complex
.
A fast algorithm is needed. You may refer to FFT Algorithm or Karatsuba Algorithm.
You need to understand your implementation fully, instead of just copy-and-pasting a piece of code from some external source. There will be an offline check where you need to explain your code to TAs.
Examples
Input 1
1 | 2 2 |
Output 1
1 | 2 5 3 |
Explanation 1
Input 2
1 | 3 5 |
Output 2
1 | 1 5 17 28 36 15 18 |
Input 3
1 | 2 3 |
Output 3
1 | 0 1 2 0 |
Problem 2. Balanced Search Tree
In this problem, you are required to implement a data structure to support the following operations.
The files attached to this problem are shown as follows. We provide some tests to help you check your code.
1 | . |
NOTE: You can not use STL data structures, such as std::unordered_map
, std::unordered_set
, std::map
and std::set
, in this problem. All of your data structure should be designed by yourself.
Requirements:
Description:
You've got a set, consisting of integers. Assume before each operation, the set contains integers, which are . You are allowed to perform five operations on this set:
- Given , insert into the set
- Given , erase from the set
- Given , query whether is in the set
- Given , query the k-th element of set i.e. .
- Given , you need to find a position such that , meanwhile minimize . You should return the minimum . In other words:
Test inference introduction
Write your code in bst.hpp
.
Our checker would first run the function void init(std::size_t n)
. Here, std::size_t n
is the number of operations we would do in this test case. In this function, you can do anything to initialize your data structure. We would guarantee that this function would be called first and only once in each test case.
Next, our checker would call long long SetOperation(std::size_t opt, long long x)
exactly times sequentially. You need to return answer values through this function call.
After each call, we would check your answer. Only if your -th answer of SetOperation
is correct, could you receive the -th function call. This means you cannot implement any off-line algorithm method in this problem.
In SetOperation
, you should do operations on your data structure according to . Assume in the -th call, there are elements in the set, which are .
There are only 5 kinds of operations:
- if , you need to insert exactly one into your data structure and return .
- if , you need to erase exactly one from your data structure and return . It is guaranteed that there exists such that .
- if , you need to answer whether is in the data structure. If is in the set, return . Otherwise, return .
- if , it is guaranteed that , and you should return .
- if , it is guaranteed that and , and you need to return the answer of query, where is
If you successfully pass all the set operations, our checker would call void clear()
, where you MUST deconstruct your data structure and release your resources.
Data constraints
In all test cases, it is guaranteed that .
Please pay attention to the special time limit and memory limit.
Time complexity
If you implement your algorithm in time, you will receive about 40 pts.
If you implement your algorithm in or time, you will receive about 70 pts.
If you implement your algorithm in time, you will receive 100 pts.
Space complexity
If you implement your algorithm in space, you will receive at most 70 pts.
To fully pass this problem, you should implement your algorithm in space.
Hint
You can use any self-balancing binary search tree to solve this problem, e.g. Scapegoat tree, AVL tree, Red-black tree, Splay tree, Treap and B-tree.
We recommend you implement Scapegoat tree. Scapegoat tree is a non-rotating binary tree. Its balancing is achieved by completely rebuild the "unbalanced" subtree into a complete binary tree. This makes Scapegoat tree easier to implement than AVL tree and Red-black tree.
Please see more information in Scapegoat Tree.
Problem 2. Calculate Huffman Coding Length
In this problem, you are required to solve a problem related to huffman coding.
Recall: Huffman coding is a lossless data compression algorithm that assigns variable-length codes to characters based on their frequency of occurrence in the input. An efficient algorithm for
generating it is related to the priority queue and covered in course slides.
The files attached to this problem are shown as follows. We provide a test to help you check your code.
1 | . |
NOTE:
- You should NEVER use
std::priority_queue
,std::map
,std::set
,std::multimap
,std::multiset
or call heap related functions likestd::make_heap()
. - In the question, you should write a more optimal algorithm that brute-force Huffman tree building to pass all tests.
Requirements:
Your task is to complete the function size_t get_huffman_length(const std::vector<std::pair<size_t, size_t>> &data)
in huffman_calculator.hpp
.
Description
Assume that we have a sequence:
1 | i a u e i y a a e a o o a a i e a |
Count the occurrence of each character:
character | occurrence |
---|---|
a | 7 |
e | 3 |
i | 3 |
o | 2 |
u | 1 |
y | 1 |
Then we generate the huffman tree (a possible solution):
Hence, we can shorten the sequence into the following format (ignore the space of storing the huffman tree):
1 | 110010011111101000001110101101001101110 |
With Huffman Coding, the sequence can be shortened to length 39 (binary).
Parameter data
In this question, we help you to ignore the process of dealing the bunch of text
.
Instead, we directly give you some pairs.
The first number (of type size_t
, named occurrence) indicate a possible number of occurrence of the character.
Occurrence will always be a positive number.
The second number (of type size_t
, named amount) indicate the number of characters satisfies the number of occurrences given by the first number.
Amount will always be a positive number.
In the example above, we have characters with occurrences (7, 3, 3, 2, 1, 1)
.
So the data
we pass to you in this example will be: [(7, 1), (3, 2), (2, 1), (1, 2)]
Return value
You need to return the length of the Huffman encoded sequence.
In this example, the return value is 39
.
Misc.
For your convenience, all the pairs we provide are guaranteed to have different occurrences.
We also guarantee that the sum of amount is larger than 1.
The data passed to your function get_huffman_length
is not guaranteed to be sorted.
Data constraints
We use to denote the number of pairs, to denote the amount in the i-th pair.
In all test cases, it is guaranteed that .
Time complexity
If your algorithm takes time, where , you will receive about 40 pts.
If your algorithm takes time, you will receive 100 pts.
Hint
The pair (10, 10)
is somehow "equivalent" to (20, 5)
.
You can calculate the return value in the process of building the huffman tree.
A heap should be most conveniently implemented using an array (or std::vector
), on which the node indexed has a left child indexed and right child indexed . Do not waste your effort on memory management of linked-list-like tree structures.
评分
评分由 OJ 分数(60%)和线下 check (40%)两部分构成。线下 check 会在此次作业结束时间之后进行。
注:线下 check 也带有检查学术诚信的含义,当然这不是唯一的手段。如果被认定为抄袭, OJ 的分数也会作废,并且会有惩罚。特别强调,抄袭来自 generative AI 的代码和抄袭网上的代码是同等处理的,我们建议您在写作业时关闭一切 generative AI 工具。