#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 nn nodes, nodes are numbered 1,2,,n1, 2, \dots, n, and node 11 is the root. Each edge has a weight from 11 to n1n - 1, and these weights are pairwise distinct. Maintain a data structure that supports swapping the weights of the two edges whose weights are xx and yy, and querying the maximum edge weight on the path from the root to node uu.

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:

  1. Given positive integers x,yx, y, where 1x,y<n1 \le x, y < n, xyx \neq y, swap the weights of the two edges whose weights are xx and yy.
  2. Given a positive integer uu, where 2un2 \le u \le n, obtain the maximum edge weight among all edges on the path from node 11 to node uu.

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 11, meaning swapping the weights of the two edges whose weights are xx and yy.
  • You must ensure 1x,y<n1 \le x, y < n, xyx \neq y.
int query(int u);
  • This function corresponds to operation 22, returning the maximum edge weight among all edges on the path from node 11 to node uu.
  • You must ensure 2un2 \le u \le n.
void answer(std::vector<int> par, std::vector<int> val);
  • This function is used to submit your final answer, with the following format:
    • par is an array of length n1n - 1, where par[i] is the parent index of node i+2i + 2, where 0in20 \le i \le n - 2.
    • val is also an array of length n1n - 1, where val[i] is the initial weight of the edge between node i+2i + 2 and its parent, where 0in20 \le i \le n - 2.
  • 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, nn is the number of nodes in the tree, lim1lim1 is the operation limit for operation 11, and lim2lim2 is the operation limit for operation 22.
  • In the final test, for each test case, the interaction library will call solve exactly once, and score your solution based on whether your call to answer is 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 n,lim1,lim2n, lim1, lim2, representing the number of nodes in the tree, the limit for operation 11, and the limit for operation 22. The interaction library guarantees it can handle 2n5000002 \le n \le 500000. For n>500000n > 500000, correct execution is not guaranteed.
  • The second line contains n1n - 1 positive integers p2,p3,,pnp_2, p_3, \dots, p_n, where pip_i is the parent index of node ii. You must ensure 1pin1 \le p_i \le n, and the input provides a valid tree structure.
  • The third line contains n1n - 1 positive integers v2,v3,,vnv_2, v_3, \dots, v_n, where viv_i is the weight of the edge from node ii to pip_i. You must ensure that v2,v3,,vnv_2, v_3, \dots, v_n form a permutation of 11 to n1n - 1.
  • 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 exchange violates 1x,y<n1 \le x, y < n, xyx \neq y, it outputs: Invalid call of exchange(x, y)! .
  • If the number of calls to exchange exceeds lim1lim1, it outputs: Too many exchanges! .
  • If any call to query violates 2un2 \le u \le n, it outputs: Invalid call of query(u)! .
  • If the number of calls to query exceeds lim2lim2, 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 par or val is not n1n - 1, it outputs Invalid output! .
    • If the par array 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 2in2 \le i \le n, j=pij = p_i is the true parent of node ii, and k=k = par[i - 2] is what you output.
    • If par is correct but val differs 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 2in2 \le i \le n, j=vij = v_i is the true initial weight of the edge from node ii to its parent, and k=k = val[i - 2] is what you output.
    • If both par and val are correct, the interaction library outputs the number of times you called exchange and query. The output format is: Right output! cnt1 = A, cnt2= B. , where AA is the number of calls to exchange, and BB is the number of calls to query.
  • When using the provided local interaction library, you may test your program by calling answer multiple times. However, for the code you submit, if you call answer more than once, you will only get 00 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 22 is 11, and the initial weight of the edge from 11 to 22 is 22.
  • The parent of node 33 is 22, and the initial weight of the edge from 22 to 33 is 11.

One possible interaction process is as follows:

  • Call query(2), returns 22.
  • Call exchange(1, 2). Now, the weight of edge 11 to 22 is 11, and the weight of edge 22 to 33 is 22.
  • Call query(2), returns 11. Now we can know that 11 and 22 are directly connected.
  • Call query(3), returns 22.
  • Call exchange(1, 2).
  • Call query(3), returns 22. Now we can deduce that 22 and 33 are directly connected.
  • Call query(2), returns 22. Now we can deduce that after the two exchange operations, the weight of edge 11 to 22 is 22, and the weight of the edge from 22 to 33 is 11.
  • Call answer([1, 2], [2, 1]), and terminate the program.

[Sample Explanation #2]

This sample satisfies n50n \le 50 and Special Property A.

[Sample Explanation #3]

This sample satisfies n1000n \le 1000.

[Sample Explanation #4]

This sample satisfies n20000n \le 20000 and Special Property B.

[Sample Explanation #5]

This sample satisfies n100000n \le 100000 and Special Property A.

[Sample Explanation #6]

This sample satisfies n100000n \le 100000.

[Sample Explanation #7]

This sample satisfies n500000n \le 500000.

[Constraints]

Test Point n=n= lim1=lim1= lim2=lim2= Special Property
11 1010 10000011000001 A
22
33 5050 10000021000002
44
55 600600 30000033000003
66
77 10001000 11000041100004 22000042200004
88 11000051100005 22000052200005
99
1010 2000020000 30000063000006 B
1111
1212
1313 100000100000 30000073000007 A
1414
1515 30000083000008
1616
1717
1818 500000500000 35000093500009 A
1919
2020 35000103500010 B
2121
2222 35000113500011
2323
2424
2525

Special Property A:

  • Each node has at most 11 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 (n1)!(n - 1)! possible permutations.

Special Property B:

  • The tree shape is generated randomly as follows:
    • First, for each 2in2 \le i \le n, choose the parent of node ii uniformly at random among the integers in [1,i1][1, i - 1].
    • 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 (n1)!(n - 1)! possible permutations.

You can determine which special property the testdata satisfies based on the values of lim1,lim2lim1, lim2.

[Scoring]

This problem is first subject to the same restrictions as traditional problems. For example, compilation errors result in 00 points for the whole problem; runtime errors, exceeding the time limit, exceeding the memory limit, etc. result in 00 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 lim1lim1, the number of calls to query does not exceed lim2lim2, 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 O(logn)O(\log n). Under the problem limits, the interaction library runs within 44 seconds and uses at most 256256 MB of memory.

That is, you have at least 44 seconds of time and 768768 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