CF1630A And Matching 题解

发布时间:2024年01月23日

And Matching

传送门

You are given a set of n n n ( n n n is always a power of 2 2 2) elements containing all integers 0 , 1 , 2 , … , n ? 1 0, 1, 2, \ldots, n-1 0,1,2,,n?1 exactly once.

Find n 2 \frac{n}{2} 2n? pairs of elements such that:

  • Each element in the set is in exactly one pair.
  • The sum over all pairs of the bitwise AND of its elements must be exactly equal to k k k. Formally, if a i a_i ai? and b i b_i bi? are the elements of the i i i-th pair, then the following must hold:
    Σ i = 1 n / 2 a i & b i = k , \Sigma_{i=1}^{n/2}{a_i \& b_i} = k, Σi=1n/2?ai?&bi?=k,
    where & \& & denotes the bitwise AND operation.

If there are many solutions, print any of them, if there is no solution, print ? 1 -1 ?1 instead.

Input

The input consists of multiple test cases. The first line contains a single integer t t t ( 1 ≤ t ≤ 400 1 \leq t \leq 400 1t400) — the number of test cases. Description of the test cases follows.

Each test case consists of a single line with two integers n n n and k k k ( 4 ≤ n ≤ 2 16 4 \leq n \leq 2^{16} 4n216, n n n is a power of 2 2 2, 0 ≤ k ≤ n ? 1 0 \leq k \leq n-1 0kn?1).

The sum of n n n over all test cases does not exceed 2 16 2^{16} 216. All test cases in each individual input will be pairwise different.

Output

For each test case, if there is no solution, print a single line with the integer ? 1 -1 ?1.

Otherwise, print n 2 \frac{n}{2} 2n? lines, the i i i-th of them must contain a i a_i ai? and b i b_i bi?, the elements in the i i i-th pair.

If there are many solutions, print any of them. Print the pairs and the elements in the pairs in any order.

Example #1

Input #1

4
4 0
4 1
4 2
4 3

Output #1

0 3
1 2
0 2
1 3
0 1
2 3
-1

Note

In the first test, ( 0 & 3 ) + ( 1 & 2 ) = 0 (0\&3)+(1\&2) = 0 (0&3)+(1&2)=0.

In the second test, ( 0 & 2 ) + ( 1 & 3 ) = 1 (0\&2)+(1\&3) = 1 (0&2)+(1&3)=1.

In the third test, ( 0 & 1 ) + ( 2 & 3 ) = 2 (0\&1)+(2\&3) = 2 (0&1)+(2&3)=2.

In the fourth test, there is no solution.

题目翻译

给你一个由 n n n n n n 总是 2 2 2 的幂次)元素组成的集合,其中包含所有整数 0 , 1 , 2 , … , n ? 1 0, 1, 2, \ldots, n-1 0,1,2,,n?1 恰好一次。

请找出 n 2 \frac{n}{2} 2n? 对元素,使得:

  • 集合中的每个元素都正好在一对中。
  • 所有元素对的 bitwise AND之和必须恰好等于 k k k 。形式上,如果 a i a_i ai? b i b_i bi? i i i -th 对中的元素,那么下面的条件必须成立:
    Σ i = 1 n / 2 a i & b i = k , \Sigma_{i=1}^{n/2}{a_i \& b_i} = k, Σi=1n/2?ai?&bi?=k,
    其中 & \& & 表示位操作 AND。

如果有多个解,则打印任意一个;如果没有解,则打印 ? 1 -1 ?1

输入格式

输入由多个测试用例组成。第一行包含一个整数 t t t ( 1 ≤ t ≤ 400 1 \leq t \leq 400 1t400 ) - 测试用例的数量。测试用例说明如下。

每个测试用例由一行和两个整数 n n n k k k 4 ≤ n ≤ 2 16 4 \leq n \leq 2^{16} 4n216 n n n 2 2 2 0 ≤ k ≤ n ? 1 0 \leq k \leq n-1 0kn?1 的幂次)组成。

所有测试用例的 n n n 之和不超过 2 16 2^{16} 216 。每个输入项中的所有测试用例都是成对不同的

输出格式

对于每个测试用例,如果没有解决方案,则打印一行,其中包含整数 ? 1 -1 ?1

否则,打印 n 2 \frac{n}{2} 2n? 行,其中 i i i 行必须包含 a i a_i ai? b i b_i bi? ,即 i i i 对中的元素。

如果有多个解,则打印任意一个。按任意顺序打印解对和解对中的元素。

提示

在第一次测试中, ( 0 & 3 ) + ( 1 & 2 ) = 0 (0\&3)+(1\&2) = 0 (0&3)+(1&2)=0

在第二次测试中, ( 0 & 2 ) + ( 1 & 3 ) = 1 (0\&2)+(1\&3) = 1 (0&2)+(1&3)=1

第三次测试, ( 0 & 1 ) + ( 2 & 3 ) = 2 (0\&1)+(2\&3) = 2 (0&1)+(2&3)=2

在第四次测试中,无解。

以上来自 C o d e F o r c e s ,翻译: D e e p L 以上来自CodeForces,翻译:DeepL 以上来自CodeForces,翻译:DeepL

解题思路

解这题需要的重要性质:

  • 0 & k = 0 0\And k=0 0&k=0
  • k & ( n ? 1 ? k ) = 0 k\And (n?1?k)=0 k&(n?1?k)=0
  • ( n ? 1 ) & k = k (n?1)\And k=k (n?1)&k=k

其中 n = 2 x ( x ∈ Z ) n=2^x(x\in Z) n=2x(xZ)

依据以上性质进行讨论:

  • n = 4 n=4 n=4 k = 3 k=3 k=3 时,无解,输出 ? 1 -1 ?1
  • k = 0 k=0 k=0:由性质 1 1 1 可知,可将 n n n 个数分成 ( 0 , n ? 1 ) , ( 1 , n ? 2 ) , … , ( n 2 ? 1 , n 2 ) (0,n-1),(1,n-2),\dots ,(\frac{n}{2}-1,\frac{n}{2}) (0,n?1),(1,n?2),,(2n??1,2n?),这样每组按位与结果都是 0 0 0
  • 0 < k < n ? 1 0<k<n?1 0<k<n?1:将 k = 0 k=0 k=0 的情况进行调整,使其中一组按位与得到 k k k,且保持其它所有组按位与结果为 0 0 0
    由性质 3 3 3,可以让 k k k n ? 1 n?1 n?1 放在一组使按位与结果是 k k k。这时对于 k = 0 k=0 k=0 时情况的分组,相当于拆掉了 ( 0 , n ? 1 ) , ( k , n ? k ? 1 ) (0,n?1),(k,n?k?1) (0,n?1),(k,n?k?1) 两组。让 k k k n ? 1 n?1 n?1 放在一组,那么 0 0 0 n ? k ? 1 n?k?1 n?k?1 放在一起,根据性质 1 1 1,按位与结果正好是 0 0 0,其他保持不变。
  • k = n ? 1 k=n?1 k=n?1:按照情况 2 的方法,让 k k k n ? 1 n?1 n?1 放在一组,但当 k = n ? 1 k=n?1 k=n?1 时无效。这时考虑将 k k k 拆成 k ? 1 k?1 k?1 1 1 1 n ? 1 n?1 n?1 n ? 2 n?2 n?2 放在一组得到 k ? 1 k?1 k?1 1 1 1 和一个奇数放在一起得到 k ? 1 k?1 k?1,也就是 n ? 2 n?2 n?2
    依据情况 1 1 1 的分组方法,若 n ? 1 n?1 n?1 n ? 2 n?2 n?2 放在一组, 1 1 1 和一个奇数放在一起,则拆掉了 ( 0 , n ? 1 ) , ( 1 , n ? 2 ) (0,n?1),(1,n?2) (0,n?1),(1,n?2) 两组。选取一个奇数与 1 1 1 搭配,易想到用 n ? 3 n?3 n?3 来搭配,这时 0 0 0 2 2 2 搭配。故最终结果: ( 0 , 2 ) , ( 1 , n ? 3 ) , ( n ? 1 , n ? 2 ) , ( 3 , n ? 4 ) , … , ( n 2 ? 1 , n 2 ) (0,2),(1,n-3),(n-1,n-2),(3,n-4),\dots ,(\frac{n}{2}-1,\frac{n}{2}) (0,2),(1,n?3),(n?1,n?2),(3,n?4),,(2n??1,2n?)

最后,将这四种情况分别用代码实现,就是AC代码了。

AC Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, k;
inline void solve();
inline void work() {
	int T;
	cin >> T;
	while (T--) {
		solve();
	}
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	work();
	return 0;
}
inline void solve() {
	cin >> n >> k;
	if (n == 4 && k == 3) {
		cout << -1 << endl;
		return;
	}
	if (k == n - 1) {
		cout << n - 1 << " " << n - 2 << endl << 1 << " " << n - 3 << endl << 0 << " " << ((n - 3) ^ (n - 1)) << endl;
		for (int i = 3; i < n / 2; i++) {
			cout << i << " " << ((n - 1)^i) << endl;
		}
	} else {
		cout << n - 1 << " " << k << endl;
		if (k != 0) {
			cout << 0 << " " << ((n - 1)^k) << endl;
		}
		for (int i = 1; i < n / 2; i++) {
			if (i == k || i == ((n - 1)^k)) {
				continue;
			}
			cout << i << " " << ((n - 1)^i) << endl;
		}
	}
}//创作不易,你敢抄袭?!
文章来源:https://blog.csdn.net/BestMonkey/article/details/135764576
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。