title: "CF 2189C2 - XOR-convenience (Hard Version)"
description: "We need to build a permutation $p$ of the numbers $1 ldots n$. For every position $i$ from $1$ to $n-1$, there must exist some position $j ge i$ such that $$pi = pj oplus i." date: "2026-06-07T21:11:39+07:00" tags: ["codeforces", "competitive-programming", "bitmasks", "constructive-algorithms", "math"] categories: ["algorithms"] codeforces_contest: 2189 codeforces_index: "C2" codeforces_contest_name: "Codeforces Round 1075 (Div. 2)" rating: 1800 weight: 2189 solve_time_s: 127 verified: true draft: false --- CF 2189C2 - XOR-convenience (Hard Version) Rating: 1800 Tags: bitmasks, constructive algorithms, math Solve time: 2m 7s Verified: yes ## Solution ## Problem Understanding We need to build a permutation $p$ of the numbers $1 \ldots n$. For every position $i$ from $1$ to $n-1$, there must exist some position $j \ge i$ such that$$p_i = p_j \oplus i.$$
Since XOR is reversible, this is equivalent to saying that for every position $i$,
$$p_j = p_i \oplus i$$
must appear somewhere at or after position $i$.
The input contains multiple values of $n$, and for each one we either output a valid permutation or report that no such permutation exists.
The largest value of $n$ is $2 \cdot 10^5$, and the sum of all $n$ over the test file is also at most $2 \cdot 10^5$. That immediately rules out anything involving permutation search, backtracking, or even $O(n^2)$ verification. We need a direct constructive formula that produces the answer in linear time.
The tricky part is that the condition depends simultaneously on positions and values. A construction that looks locally correct can easily fail because the required value appears before position $i$, while the problem requires it to appear at some position $j \ge i$.
One important edge case is when $n$ is a power of two.
For example:
n = 4
The correct output is:
-1
A naive attempt to adapt the easy-version construction fails here because the value $4$ has no valid XOR partner inside the range $1 \ldots 4$.
Another subtle case is an even $n$ that is not a power of two.
For example:
n = 6
The easy-version construction almost works, but position $1$ becomes invalid. A small modification is required. Missing this modification produces a permutation that satisfies all positions except the first one.
Odd values of $n$ behave differently.
For example:
n = 7
The basic pairing construction already satisfies every position, including $i=1$. A solution that treats odd and even $n$ identically will generally fail.
## Approaches
A brute-force approach would try permutations and check whether every position satisfies the condition. Checking one permutation costs $O(n^2)$ in the worst case because for each $i$ we may need to search all later positions. Since there are $n!$ permutations, this becomes hopeless even for very small $n$.
The key observation comes from looking at the easy version.
Suppose we place
$$p_i = i \oplus 1$$
for most positions. Since XOR with $1$ simply swaps adjacent numbers,
$$2 \leftrightarrow 3,\quad
4 \leftrightarrow 5,\quad
6 \leftrightarrow 7,\ldots$$
we obtain many identities of the form
$$p_i = p_{i+1} \oplus i.$$
The reason is that adjacent values differ exactly by the bit represented by $i$.
The easy-version solution is
$$p_n = 1,$$
and for $2 \le i \le n-1$,
$$p_i = i \oplus 1.$$
Only the first position requires additional work.
For odd $n$, setting
$$p_1 = n-1$$
already makes position $1$ valid because
$$(n-1)\oplus 1 = n.$$
For even $n$, position $1$ breaks. The hard version is precisely about fixing that.
The crucial fact is that when $n$ is not a power of two, its lowest set bit
$$x = \operatorname{lowbit}(n)$$
satisfies $1 < x < n$.
Starting from the easy construction, we swap the values at positions $1$ and $x$.
This single swap repairs position $1$ while preserving all other positions. The XOR structure created by the adjacent pairings survives the modification.
When $n$ is a power of two, such a repair is impossible. The value $n$ cannot be matched with any valid partner inside the permutation, which leads to a contradiction. Hence no solution exists.
| Approach | Time Complexity | Space Complexity | Verdict |
| --- | --- | --- | --- |
| Brute Force | $O(n! \cdot n^2)$ | $O(n)$ | Too slow |
| Optimal Construction | $O(n)$ | $O(n)$ | Accepted |
## Algorithm Walkthrough
1. Check whether $n$ is a power of two.
If $n = 2^k$, output -1.
2. Create an array ans of length $n$.
3. Set
$$ans[n] = 1.$$
4. For every position $2 \le i \le n-1$, assign
$$ans[i] =
\begin{cases}
i+1,& i \text{ even}\
i-1,& i \text{ odd}
\end{cases}$$
This is exactly $i \oplus 1$.
5. If $n$ is odd, set
$$ans[1] = n-1.$$
6. If $n$ is even, first set
$$ans[1] = n.$$
Then compute
$$x = n ,&, (-n)$$
and swap ans[1] with ans[x].
7. Output the resulting permutation.
### Why it works
For every position $i \ge 2$, the construction pairs neighboring values using XOR with $1$. These positions already satisfy the required condition from the easy-version solution.
When $n$ is odd, position $1$ works because
$$ans[1] = n-1,
\qquad
(n-1)\oplus 1 = n,$$
and the value $n$ appears later in the permutation.
When $n$ is even and not a power of two, let $x=\operatorname{lowbit}(n)$. After swapping positions $1$ and $x$,
$$ans[1]=x+1.$$
Then
$$ans[1]\oplus1=(x+1)\oplus1=x,$$
and the value $x$ is located at position $x+1$, which is after position $1$. Position $1$ is fixed. The only other affected position is $x$, and it remains valid because
$$n\oplus x=n-x,$$
which still appears at a later position. All remaining positions are unchanged from the easy-version construction and remain valid.
For powers of two, the value $n$ cannot participate in the required XOR relationships inside the range $1 \ldots n$, making the construction impossible.
## Python Solution
python import sys input = sys.stdin.readline def solve(): t = int(input()) out = [] for _ in range(t): n = int(input()) if n & (n - 1) == 0: out.append("-1") continue ans = [0] * (n + 1) ans[n] = 1 for i in range(2, n): if i & 1: ans[i] = i - 1 else: ans[i] = i + 1 if n & 1: ans[1] = n - 1 else: ans[1] = n x = n & -n ans[1], ans[x] = ans[x], ans[1] out.append(" ".join(map(str, ans[1:]))) sys.stdout.write("\n".join(out)) solve()
The first step checks whether $n$ is a power of two using the standard bit trick n & (n - 1) == 0.
The middle loop builds the adjacent-pair structure. Every even index receives the next number and every odd index receives the previous one. This is exactly the permutation induced by XOR with 1.
For odd $n$, the value n - 1 at the first position immediately creates the needed partner through XOR with 1.
For even $n$, the lowest set bit is found with n & -n. Swapping the values at positions 1 and lowbit(n) is the entire hard-version modification. Forgetting this swap produces a construction that fails at position 1.
The implementation is linear in $n$ and uses only one array.
## Worked Examples
### Example 1
Input:
n = 3
| Step | State |
| --- | --- |
| Initialize | ans = [0,0,0] |
| ans[3] = 1 | [0,0,1] |
| i = 2 | [0,3,1] |
| Odd n, ans[1] = 2 | [2,3,1] |
Output:
2 3 1
Check position $1$:
$$2 = 3 \oplus 1.$$
Check position $2$:
$$3 = 1 \oplus 2.$$
Every condition holds.
This example shows why odd $n$ needs no additional repair.
### Example 2
Input:
n = 6
| Step | State |
| --- | --- |
| Base construction | [6,3,2,5,4,1] |
| lowbit(6)=2 | |
| Swap positions 1 and 2 | [3,6,2,5,4,1] |
Output:
3 6 2 5 4 1
Check position $1$:
$$3 \oplus 1 = 2,$$
and value $2$ appears later.
Check position $2$:
$$6 \oplus 2 = 4,$$
and value $4$ appears later.
The example demonstrates the purpose of the swap.
## Complexity Analysis
| Measure | Complexity | Explanation |
| --- | --- | --- |
| Time | $O(n)$ | Each position is assigned once |
| Space | $O(n)$ | The permutation array is stored |
The sum of all $n$ is at most $2 \cdot 10^5$, so the total running time over the entire input is linear in the input size. This easily fits within the 2-second limit.
## Test Cases
python # helper: run solution on input string, return output string import sys, io def run(inp: str) -> str: input_data = io.StringIO(inp) t = int(input_data.readline()) out = [] for _ in range(t): n = int(input_data.readline()) if n & (n - 1) == 0: out.append("-1") continue ans = [0] * (n + 1) ans[n] = 1 for i in range(2, n): ans[i] = i - 1 if i & 1 else i + 1 if n & 1: ans[1] = n - 1 else: ans[1] = n x = n & -n ans[1], ans[x] = ans[x], ans[1] out.append(" ".join(map(str, ans[1:]))) return "\n".join(out) # provided sample assert run("2\n3\n4\n") == "2 3 1\n-1" # minimum valid size assert run("1\n3\n") == "2 3 1" # power of two assert run("1\n8\n") == "-1" # even, not power of two assert run("1\n6\n") == "3 6 2 5 4 1" # odd assert run("1\n7\n") == "6 3 2 5 4 7 1"
| Test input | Expected output | What it validates |
| --- | --- | --- |
| n=3 | valid permutation | Smallest valid case |
| n=4 | -1 | Power-of-two impossibility |
| n=6 | valid permutation | Even non-power-of-two repair |
| n=7 | valid permutation | Odd construction |
| n=8 | -1 | Larger power of two |
## Edge Cases
Consider:
1 4
Since $4$ is a power of two, the algorithm immediately outputs:
-1
This is correct because no valid placement of the value $4$ can create the required XOR partner inside the range $1 \ldots 4$.
Consider:
1 6
The easy-version construction gives:
6 3 2 5 4 1
Position $1$ fails. The algorithm computes
$$\operatorname{lowbit}(6)=2$$
and swaps positions $1$ and $2$, producing
3 6 2 5 4 1
Now position $1$ becomes valid because $3 \oplus 1 = 2$, and the value $2$ appears later.
Consider:
1 7
The construction is:
6 3 2 5 4 7 1
Position $1$ is already valid because
$$6 \oplus 1 = 7.$$
No swap is needed. This demonstrates why odd and even $n$ require different handling.