結果

問題 No.2977 Kth Xor Pair
コンテスト
ユーザー kwm_t
提出日時 2026-10-22 21:21:14
言語 C++23
(gcc 15.3.0 + boost 1.92.0 + ACL)
コンパイル:
g++-15 -O2 -lm -std=c++23 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
WA  
実行時間 -
コード長 6,125 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,232 ms
コンパイル使用メモリ 343,080 KB
実行使用メモリ 48,408 KB
最終ジャッジ日時 2026-10-22 21:22:25
合計ジャッジ時間 52,711 ms
ジャッジサーバーID
(参考情報)
judge3_0 / judge2_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 35 WA * 1
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
// using mint = modint1000000007;
// const int mod = 1000000007;
// using mint = modint998244353;
// const int mod = 998244353;
const int INF = 1e9;
const long long LINF = 1e18;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i, l, r) for (int i = (l); i < (r); ++i)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; --i)
#define rrep2(i, l, r) for (int i = (r) - 1; i >= (l); --i)
#define all(x) (x).begin(), (x).end()
#define allR(x) (x).rbegin(), (x).rend()
#define P pair<int, int>
/**
* @file binary_trie.hpp
* @brief Binary Trie
* @author kwm_t
* @see https://github.com/kwm-t/cp-library/blob/main/datastructure/binary_trie.hpp
*/
#ifndef KWM_T_DATA_STRUCTURE_BINARY_TRIE_HPP
#define KWM_T_DATA_STRUCTURE_BINARY_TRIE_HPP

#include <array>
#include <vector>
#include <type_traits>

/**
* @brief Binary Trie(XOR系クエリ対応Trie)
*
* 整数を2進表現として管理するTrie
*
* 典型用途:
*   - xor最大/最小
*   - k番目の値
*   - xor制約付きカウント
*
* 計算量:
*   - 各操作 O(bit)
*
* @tparam T int / long long を想定
*
* 制約 / 注意:
*   - eraseは存在する値にのみ使用すること
*   - bit長はコンストラクタで調整可能
*
* verified:
*   - https://atcoder.jp/contests/abc451/submissions/74523720
*/
namespace kwm_t::data_structure {

	template<class T = int>
	struct BinaryTrie {
	private:
		static constexpr int default_bit() {
			if constexpr (std::is_same_v<T, int>) return 30;
			else return 60;
		}

		int bit;

		std::vector<int> node;
		std::vector<std::array<int, 2>> next;
		const std::array<int, 2> e{ -1, -1 };

		std::vector<int> trans(T x) const {
			std::vector<int> ret(bit, 0);
			for (int i = 0; i < bit; ++i) {
				if ((x >> i) & 1) ret[bit - 1 - i] = 1;
			}
			return ret;
		}

		T inverse(const std::vector<int>& v) const {
			T ret = 0;
			for (int i = 0; i < (int)v.size(); ++i) {
				ret = (ret << 1) | v[i];
			}
			return ret;
		}

	public:
		BinaryTrie(int _bit = default_bit())
			: bit(_bit) {
			node.resize(1);
			next.emplace_back(e);
		}

		static int calc_bit(T max_val) {
			int b = 0;
			while ((T(1) << b) <= max_val) b++;
			return b;
		}

		void insert(const std::vector<int>& v) {
			int now = 0;
			for (int i = 0; i < bit; ++i) {
				if (next[now][v[i]] == -1) {
					next[now][v[i]] = node.size();
					node.emplace_back(0);
					next.emplace_back(e);
				}
				now = next[now][v[i]];
				node[now]++;
			}
		}
		void insert(T x) { insert(trans(x)); }

		void erase(const std::vector<int>& v) {
			int now = 0;
			for (int i = 0; i < bit; ++i) {
				now = next[now][v[i]];
				node[now]--;
			}
		}
		void erase(T x) { erase(trans(x)); }

		bool search(const std::vector<int>& v) const {
			int now = 0;
			for (int i = 0; i < bit; ++i) {
				if (next[now][v[i]] == -1) return false;
				if (node[next[now][v[i]]] <= 0) return false;
				now = next[now][v[i]];
			}
			int cnt = node[now];
			for (int i = 0; i < 2; ++i) {
				if (next[now][i] != -1) cnt -= node[next[now][i]];
			}
			return cnt > 0;
		}
		bool search(T x) const { return search(trans(x)); }

		vector<int> kth_element_vec(int k) const {
			int now = 0;
			std::vector<int> v;
			while (true) {
				bool ok = false;
				for (int i = 0; i < 2; ++i) {
					if (next[now][i] == -1) continue;
					if (k <= node[next[now][i]]) {
						v.push_back(i);
						now = next[now][i];
						ok = true;
						break;
					}
					else {
						k -= node[next[now][i]];
					}
				}
				if (!ok) break;
			}
			return v;
		}
		T kth_element(int k) const { return inverse(kth_element_vec(k)); }

		std::vector<int> xor_max(const std::vector<int>& v) const {
			std::vector<int> ret;
			int now = 0;
			for (int i = 0; i < bit; ++i) {
				int want[2] = { 1 - v[i], v[i] };
				for (int t : want) {
					if (next[now][t] == -1) continue;
					if (node[next[now][t]] <= 0) continue;
					ret.push_back(t);
					now = next[now][t];
					break;
				}
			}
			return ret;
		}
		T xor_max(T x) const { return inverse(xor_max(trans(x))); }

		std::vector<int> xor_min(const std::vector<int>& v) const {
			std::vector<int> ret;
			int now = 0;
			for (int i = 0; i < bit; ++i) {
				int want[2] = { v[i], 1 - v[i] };
				for (int t : want) {
					if (next[now][t] == -1) continue;
					if (node[next[now][t]] <= 0) continue;
					ret.push_back(t);
					now = next[now][t];
					break;
				}
			}
			return ret;
		}
		T xor_min(T x) const { return inverse(xor_min(trans(x))); }

		int xor_count(const std::vector<int>& vx, const std::vector<int>& vk) const {
			int ret = 0, now = 0;
			for (int i = 0; i < bit; ++i) {
				if (vk[i] == 0) {
					if (next[now][vx[i]] == -1) break;
					now = next[now][vx[i]];
				}
				else {
					if (next[now][vx[i]] != -1)
						ret += node[next[now][vx[i]]];
					if (next[now][1 - vx[i]] == -1) break;
					now = next[now][1 - vx[i]];
				}
			}
			return ret;
		}
		int xor_count(T x, T k) const { return xor_count(trans(x), trans(k)); }

		int over_count(const std::vector<int>& v) const {
			int ret = 0, now = 0;
			for (int i = 0; i < bit; ++i) {
				if (v[i] == 0) {
					if (next[now][1] != -1)
						ret += node[next[now][1]];
				}
				if (next[now][v[i]] == -1) break;
				now = next[now][v[i]];
			}
			return ret;
		}
		int over_count(T x) const { return over_count(trans(x)); }

		int size() const { return node[0]; }
	};

} // namespace kwm_t::data_structure

#endif // KWM_T_DATA_STRUCTURE_BINARY_TRIE_HPP
template <class T, class F>
T binarySearch(T ok, T ng, const F& f) {
	while (abs(ok - ng) > 1) {
		T mid = (ok + ng) / 2;
		(f(mid) ? ok : ng) = mid;
	}
	return ok;
}
int main() {
	int n; cin >> n;
	long long k; cin >> k;
	kwm_t::data_structure::BinaryTrie<int> trie;
	vector<int>a(n);
	rep(i, n)cin >> a[i];
	rep(i, n) {
		trie.insert(a[i]);
	}
	auto f = [&](const long long x)->bool {
		long long cnt = 0;
		rep(i, n) {
			cnt += trie.xor_count(a[i], x + 1) - 1;
		}
		cnt /= 2;
		return k <= cnt;
		};
	auto ans = binarySearch<long long>((1 << 30), -1, f);
	cout << ans << endl;
	return 0;
}
0