#P9075. [WC/CTS2023] 树据结构
[WC/CTS2023] 树据结构
Background
This is an interactive problem.
Before submitting this problem, be sure to read the following carefully.
This problem only supports C++ submissions (C++14 is recommended; please do not use C++14 (GCC9)).
Due to Luogu’s special interaction mechanism, when submitting this problem, please remove the line #include "ds.h" from your code, and paste the following content at the very beginning of your code, then submit:
#include <vector>
void exchange(int x, int y);
int query(int u);
void answer(std::vector<int> par, std::vector<int> val);
If you encounter any unexpected situation when submitting this problem, please contact an administrator.
Problem Description
As an experienced OI contestant, you are already very familiar with all kinds of data structure problems. In contests, whenever you see a data structure problem, you can solve it quickly and easily. One day, you open an OJ and see this problem:
Given a rooted tree with nodes, nodes are numbered , and node is the root. Each edge has a weight from to , and these weights are pairwise distinct. Maintain a data structure that supports swapping the weights of the two edges whose weights are and , and querying the maximum edge weight on the path from the root to node .
Such a simple and classic tree problem is nothing difficult for you. Tired of maintaining updates and answering queries, you decide to switch roles. This time, you are the one asking questions, and you need to design suitable operations to extract the hidden data of the problem.
More specifically, now you do not know the tree structure, nor the initial edge weights. You need to obtain the tree structure and the initial weight of every edge through the following two operations:
- Given positive integers , where , , swap the weights of the two edges whose weights are and .
- Given a positive integer , where , obtain the maximum edge weight among all edges on the path from node to node .
The problem guarantees that the tree shape and every edge weight are fixed in advance, and will not be generated dynamically based on your operations.
[Implementation Details]
You need to include the header file #include "ds.h". You can call the following functions to interact with the interaction library:
void exchange(int x, int y);
- This function corresponds to operation , meaning swapping the weights of the two edges whose weights are and .
- You must ensure , .
int query(int u);
- This function corresponds to operation , returning the maximum edge weight among all edges on the path from node to node .
- You must ensure .
void answer(std::vector<int> par, std::vector<int> val);
- This function is used to submit your final answer, with the following format:
paris an array of length , wherepar[i]is the parent index of node , where .valis also an array of length , whereval[i]is the initial weight of the edge between node and its parent, where .
- You must call this function exactly once!
You do not need to, and should not, implement the main function. In this problem, you only need to implement the following function:
void solve(int n, int lim1, int lim2);
- Here, is the number of nodes in the tree, is the operation limit for operation , and is the operation limit for operation .
- In the final test, for each test case, the interaction library will call
solveexactly once, and score your solution based on whether your call toansweris correct.
In the attachments, we provide sample.cpp for your reference. You may implement your program based on it.
[How to Test with the Local Grader]
The attachments provide grader.cpp. The interaction library used in the final test is different from the provided local interaction library, so your implementation must not rely on the specific implementation details of the provided library.
You need to place your program ds.cpp together with grader.cpp and ds.h in the same directory, and compile in that directory using the following command to obtain the executable ds(.exe):
g++ -o ds ds.cpp grader.cpp -O2 -std=c++14 -lm
The attachments also provide compile.sh, whose content is this compile command. You can run it to compile, or copy the compile command from it to compile.
The executable reads input from standard input in the following format:
- The first line contains three positive integers , representing the number of nodes in the tree, the limit for operation , and the limit for operation . The interaction library guarantees it can handle . For , correct execution is not guaranteed.
- The second line contains positive integers , where is the parent index of node . You must ensure , and the input provides a valid tree structure.
- The third line contains positive integers , where is the weight of the edge from node to . You must ensure that form a permutation of to .
- When testing locally, be sure your input format meets the requirements; otherwise we do not guarantee that the interaction library will run normally.
If your input is valid and there is no runtime error, the provided interaction library will output the following messages based on your calls:
- If any call to
exchangeviolates , , it outputs:Invalid call of exchange(x, y)!. - If the number of calls to
exchangeexceeds , it outputs:Too many exchanges!. - If any call to
queryviolates , it outputs:Invalid call of query(u)!. - If the number of calls to
queryexceeds , it outputs:Too many queries!. - After outputting any of the above error messages, the interaction library terminates immediately.
- The interaction library outputs a prompt message every time you call
answer:- If the length of
parorvalis not , it outputsInvalid output!. - If the
pararray differs from the tree structure, it reports the first wrong position and returns:The answer to p[i] is wrong! The right answer is j, but you output k.. Note that here , is the true parent of node , andpar[i - 2]is what you output. - If
paris correct butvaldiffers from the initial edge weights, it reports the first wrong position and returns:The answer to v[i] is wrong! The right answer is j, but you output k.. Similarly, here , is the true initial weight of the edge from node to its parent, andval[i - 2]is what you output. - If both
parandvalare correct, the interaction library outputs the number of times you calledexchangeandquery. The output format is:Right output! cnt1 = A, cnt2= B., where is the number of calls toexchange, and is the number of calls toquery.
- If the length of
- When using the provided local interaction library, you may test your program by calling
answermultiple times. However, for the code you submit, if you callanswermore than once, you will only get points.
Your program should not read from or write to standard input/output; otherwise it will be considered an attack on the interaction library.
Input Format
See [How to Test with the Local Grader].
Output Format
See [How to Test with the Local Grader].
3 100 100
1 2
2 1
Right output! cnt1 = 2, cnt2 = 5.
见附件中的 ds2.in
见附件中的 ds2.ans
见附件中的 ds3.in
见附件中的 ds3.ans
见附件中的 ds4.in
见附件中的 ds4.ans
见附件中的 ds5.in
见附件中的 ds5.ans
见附件中的 ds6.in
见附件中的 ds6.ans
见附件中的 ds7.in
见附件中的 ds7.ans
Hint
[Sample Explanation #1]
One possible input is as follows:
- The parent of node is , and the initial weight of the edge from to is .
- The parent of node is , and the initial weight of the edge from to is .
One possible interaction process is as follows:
- Call
query(2), returns . - Call
exchange(1, 2). Now, the weight of edge to is , and the weight of edge to is . - Call
query(2), returns . Now we can know that and are directly connected. - Call
query(3), returns . - Call
exchange(1, 2). - Call
query(3), returns . Now we can deduce that and are directly connected. - Call
query(2), returns . Now we can deduce that after the twoexchangeoperations, the weight of edge to is , and the weight of the edge from to is . - Call
answer([1, 2], [2, 1]), and terminate the program.
[Sample Explanation #2]
This sample satisfies and Special Property A.
[Sample Explanation #3]
This sample satisfies .
[Sample Explanation #4]
This sample satisfies and Special Property B.
[Sample Explanation #5]
This sample satisfies and Special Property A.
[Sample Explanation #6]
This sample satisfies .
[Sample Explanation #7]
This sample satisfies .
[Constraints]
| Test Point | Special Property | |||
|---|---|---|---|---|
| A | ||||
| B | ||||
| A | ||||
| A | ||||
| B | ||||
Special Property A:
- Each node has at most child, i.e. the tree is a chain.
- The labels of non-root nodes on the chain are uniformly random among all possible labelings.
- The edge-weight permutation is uniformly random among all possible permutations.
Special Property B:
- The tree shape is generated randomly as follows:
- First, for each , choose the parent of node uniformly at random among the integers in .
- Then uniformly randomly shuffle the labels of non-root nodes, obtaining the final labeled rooted tree structure.
- The edge-weight permutation is uniformly random among all possible permutations.
You can determine which special property the testdata satisfies based on the values of .
[Scoring]
This problem is first subject to the same restrictions as traditional problems. For example, compilation errors result in points for the whole problem; runtime errors, exceeding the time limit, exceeding the memory limit, etc. result in points for the corresponding test points. You may only access variables you define and those provided by the interaction library, and their corresponding memory; attempting to access other memory may cause compilation errors or runtime errors.
Under the above conditions, you can obtain the score for a test point if and only if the parameter format of every call is correct, the number of calls to exchange does not exceed , the number of calls to query does not exceed , and the par and val arrays given in your first call to answer are correct.
It is guaranteed that, in both the provided interaction library and the final judging interaction library, the worst-case complexity of a single call to exchange and query is . Under the problem limits, the interaction library runs within seconds and uses at most MB of memory.
That is, you have at least seconds of time and MB of memory available.
[Reminder]
We remind you again: the tree shape and every edge weight are fixed in advance, and will not be generated dynamically based on your operations.
You need to pay attention to your program’s time cost and memory cost.
Gaining points by accessing input/output files, attacking the judging system, or attacking the judging library is considered cheating, and the score obtained will be invalid.
Translated by ChatGPT 5