题目描述
这是一道交互题。
Iliyan 对 Jonas 开了一个恶作剧:他藏起了整数 0 到 N−1 的一个排列 p0,p1,…,pN−1。Jonas 很想恢复这个排列,而你答应帮助他。
Iliyan 不会直接公布排列,但同意回答如下问题:你可以选择满足 0≤i,j<N 的两个下标 i 和 j,他会告诉你 pi 与 pj 的按位异或值。
两个数的按位异或记为 ⊕,它会对每一对对应的二进制位执行逻辑异或。恰有一个输入位为 1 时,结果位为 1;否则结果位为 0。例如,75⊕29=86,因为 1001011(2)⊕0011101(2)=1010110(2)。在 C++ 中,a 与 b 的异或写作 a ^ b。
Iliyan 最多愿意回答 Q 个问题。
然而,这些问题不一定能唯一确定隐藏排列。若对于每对满足 0≤i,j<N 的下标,都有 ai⊕aj=pi⊕pj,则称排列 a0,a1,…,aN−1 与 p 不可区分。无论隐藏排列是 p 还是 a,Iliyan 给出的所有回答都完全相同,因此任何询问序列都无法区分二者。p 总是与自身不可区分,也可能不存在其他与它不可区分的排列。
你的任务是求出与 p 不可区分的字典序最小排列。
若在排列 x0,x1,…,xN−1 与 y0,y1,…,yN−1 第一个不同的位置 k 上有 xk<yk,则称 x 的字典序小于 y。例如,[2,0,1,4,3] 的字典序小于 [2,0,3,1,4],因为它们第一个不同的位置是 k=2,且 1<3。
隐藏排列在程序开始前便已固定,不会根据你的询问发生改变。
实现细节
你需要实现以下函数:
std::vector<int> solve(int N)
该函数恰好调用 T 次,每个隐藏排列调用一次。它必须返回与本次调用所隐藏排列不可区分的字典序最小排列。
你可以调用以下函数与评测器通信:
int get_xor(int i, int j)
每次调用返回 pi⊕pj。两个参数都必须是合法下标,否则程序会得到 Output isn't correct: Invalid argument。该函数会在 O(1) 时间内返回。
Q 的值由子任务固定,不会传给你的程序。
输入格式
输入格式:
- 第 1 行:两个整数 T 和 Qtype,其中 Qtype 为 1 或 2;
- 接下来的 2T 行描述各个测试:
- 第 2i 行:一个整数 Ni;
- 第 2i+1 行:Ni 个整数 p0,p1,…,pNi−1。
若 Qtype=1,则 Qi=Ni;若 Qtype=2,则 Qi=Ni2。
输出格式
输出格式:
- 第 i 行:程序在第 i 个测试中返回的排列。
提示
样例
考虑如下交互,其中 solve 被调用两次:
| 选手程序 |
评测程序 |
|
solve(4) |
get_xor(0, 1) |
返回 2 |
get_xor(0, 2) |
返回 3 |
get_xor(0, 3) |
返回 1 |
get_xor(1, 2) |
get_xor(1, 3) |
返回 3 |
get_xor(2, 3) |
返回 2 |
return {0, 2, 3, 1} |
|
|
solve(1) |
return {0} |
|
第一次调用解释
隐藏排列为 [2,0,1,3],但与它不可区分的字典序最小排列为 [0,2,3,1]。本次调用中 N1=4,共询问 6 次;由于该子任务中 Q1=N12=16,因此询问次数合法。
第二次调用解释
当 N2=1 时,唯一可能的排列为 [0]。
限制
- 对每个 1≤i≤T,均有 1≤Ni≤220,其中 Ni 是第 i 次调用
solve 时的 N
- 1≤T≤210
- T⋅max(N1,N2,…,NT)≤225
- 第 i 次调用
solve 时,最多可询问 Qi 次;根据子任务不同,Qi 为 Ni 或 Ni2
子任务
| 子任务 |
分值 |
Ni |
T |
Qi |
附加限制 |
| 0 |
- |
Ni2 |
样例。 |
| 1 |
7 |
≤23 |
210 |
- |
| 2 |
18 |
≤27 |
25 |
| 3 |
5 |
≤211 |
| 4 |
Ni |
| 5 |
≤218 |
对某个整数 k,有 Ni=2k。 |
| 6 |
Ni 为奇数。 |
| 7 |
30 |
- |
| 8 |
25 |
≤220 |