F. Lisa and the Martians codeforces 1851F

Problem - F - Codeforces

题目大意:有n个小于2的k次方的数,要求从中选两个数ai,aj,然后选择一个任意的小于2的k次方的数x,使(ai^x)&(aj^x),求ai,aj,x

2<=n<=2e5;1<=k<=30

思路:因为ai^x使两个数不同的部分,而ai和aj都^了同一个数,所以最终结果就等于ai和ai相同的部分,也就是两个数的同或,但同或不好求,要求同或最大可以求异或最小所以我们将原数组从小到大排序,最小值一定出现在两个相邻数,然后找每两个相邻数异或最小值,x即为选出的数其中之一的2的k次方以内的反码,即(1<

//#include<__msvc_all_public_headers.hpp>
#include
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
pair a[N];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while (t--)
	{
		int n, k;
		cin >> n >> k;
		for (int i = 1; i <= n; i++)
		{
			cin >> a[i].first;
			a[i].second = i;
		}
		sort(a + 1, a + n + 1);
		ll ma = 0x7fffffff, it = -1;
		for (int i = 1; i <= n-1; i++)
		{
			ll temp = a[i].first ^ a[i + 1].first;//两个数距离越近,异或越小
			if (temp < ma)
			{
				ma = temp, it = i;
			}
		}
		//cout << "ans:";
		ll temp = (1 << k) - 1;
		cout << a[it].second << " " << a[it + 1].second << " " << (temp ^ a[it].first) << endl;
	}
	return 0;
}

你可能感兴趣的:(位运算,算法,c++)