結果

問題 No.130 XOR Minimax
ユーザー 👑 jupirojupiro
提出日時 2020-01-11 00:18:34
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 155 ms / 5,000 ms
コード長 3,950 bytes
コンパイル時間 1,014 ms
コンパイル使用メモリ 115,628 KB
実行使用メモリ 50,908 KB
最終ジャッジ日時 2023-10-10 00:25:19
合計ジャッジ時間 3,719 ms
ジャッジサーバーID
(参考情報)
judge13 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 77 ms
23,820 KB
testcase_01 AC 1 ms
4,352 KB
testcase_02 AC 2 ms
4,352 KB
testcase_03 AC 2 ms
4,352 KB
testcase_04 AC 24 ms
4,352 KB
testcase_05 AC 49 ms
4,348 KB
testcase_06 AC 49 ms
9,604 KB
testcase_07 AC 61 ms
9,636 KB
testcase_08 AC 143 ms
50,908 KB
testcase_09 AC 12 ms
5,128 KB
testcase_10 AC 17 ms
5,856 KB
testcase_11 AC 55 ms
7,932 KB
testcase_12 AC 6 ms
4,416 KB
testcase_13 AC 47 ms
7,616 KB
testcase_14 AC 155 ms
41,808 KB
testcase_15 AC 3 ms
4,348 KB
testcase_16 AC 108 ms
30,884 KB
testcase_17 AC 110 ms
31,924 KB
testcase_18 AC 119 ms
33,980 KB
testcase_19 AC 143 ms
39,284 KB
testcase_20 AC 68 ms
21,864 KB
testcase_21 AC 151 ms
41,532 KB
testcase_22 AC 30 ms
12,276 KB
testcase_23 AC 11 ms
6,120 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
#include <functional>
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long MAX = 5100000;
const long long INF = 1LL << 60;
const long long MOD = 1'000'000'007LL;
//const long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;

template<typename T = unsigned int, int B = 32>
struct BinaryTrie {
private:
	struct Node {
		int cnt;
		T lazy;
		Node *ch[2] = {};

		Node() :cnt(0), lazy(0) {}
	};

	Node* root;

	int size(Node *t) { return t ? t->cnt : 0; }

	void eval(Node* t, int bit_index) {
		if (!t->lazy)return;
		if (t->lazy >> bit_index)swap(t->ch[0], t->ch[1]);
		if (t->ch[0])t->ch[0]->lazy ^= t->lazy;
		if (t->ch[1])t->ch[1]->lazy ^= t->lazy;
		t->lazy = 0;
	}

	Node* insert(Node* t, T n, int bit_index) {
		if (!t)t = new Node;
		t->cnt += 1;
		if (bit_index == -1)return t;
		eval(t, bit_index);
		bool c = (n >> bit_index) & 1;
		t->ch[c] = insert(t->ch[c], n, bit_index - 1);
		return t;
	}

	Node* erase(Node* t, T n, int bit_index) {
		//assert(t);
		t->cnt -= 1;
		if (!t->cnt)return nullptr;
		if (bit_index == -1)return t;
		eval(t, bit_index);
		bool c = (n >> bit_index) & 1;
		t->ch[c] = erase(t->ch[c], n, bit_index - 1);
		return t;
	}

	T get_min(Node* t, T n, int bit_index) {
		//assert(t);
		if (bit_index<0)return 0;
		eval(t, bit_index);
		bool c = (n >> bit_index) & 1;
		T ret = 0;
		if (!t->ch[c])c ^= 1;
		return get_min(t->ch[c], n, bit_index - 1) | ((T)c << bit_index);
	}

	T get(Node* t, T n, int k, int bit_index) {
		//assert(t&&t->cnt<=k);
		if (bit_index<0)return 0;
		eval(t, bit_index);
		bool c = (n >> bit_index) & 1;
		if (size(t->ch[c])<k)k -= size(t->ch[c]), c ^= 1;
		return get(t->ch[c], n, k, bit_index - 1) | ((T)c << bit_index);
	}

	int count_lower(Node* t, T n, T val, int bit_index) {
		if (!t || bit_index<0)return 0;
		eval(t, bit_index);
		bool c = (n >> bit_index) & 1;
		int ret = 0;
		if ((val >> bit_index) & 1)ret += size(t->ch[c]), c ^= 1;
		return ret + count_lower(t->ch[c], n, val, bit_index - 1);
	}

	T calc(Node* t, int bit_index) {
		if (!t || bit_index<0)return 0;
		if (size(t->ch[0]) == 0)return calc(t->ch[1], bit_index - 1);
		if (size(t->ch[1]) == 0)return calc(t->ch[0], bit_index - 1);
		T ret = (1LL << bit_index) + min(calc(t->ch[0], bit_index - 1), calc(t->ch[1], bit_index - 1));
		return ret;
	}

public:
	BinaryTrie() :root(nullptr) {}

	int size() {
		return size(root);
	}

	bool empty() {
		return !root;
	}

	void insert(T n) {
		root = insert(root, n, B - 1);

	}

	void erase(T n) {
		root = erase(root, n, B - 1);
	}

	void xor_all(T n) {
		if (root) root->lazy ^= n;
	}

	T max_element(T bias = 0) {
		return get_min(root, ~bias, B - 1);
	}

	T min_element(T bias = 0) {
		return get_min(root, bias, B - 1);
	}

	int lower_bound(T x, T bias = 0) {
		return count_lower(root, bias, x, B - 1);
	}

	int upper_bound(T x, T bias = 0) {
		return count_lower(root, bias, x + 1, B - 1);
	}

	int count(T x) {
		return upper_bound(x) - lower_bound(x);
	}

	T get(int k, T bias = 0) {
		//assert(0<=k&&k<size());
		return get(root, bias, k + 1, B - 1);
	}

	T operator[](int k) {
		return get(k);
	}

	T calc() {
		return calc(root, B - 1);
	}

};
int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/

	int n; cin >> n;
	BinaryTrie<> bt;
	for (ll i = 0; i < n; i++) {
		int x; cin >> x;
		bt.insert(x);
	}
	cout << bt.calc() << endl;
	return 0;
}
0