Submission #763885

#TimeUsernameProblemLanguageResultExecution timeMemory
763885NK_XOR (IZhO12_xor)C++17
100 / 100
200 ms59380 KiB
#include <bits/stdc++.h>

using namespace std;

#define nl '\n'

const int INF = 1e9+10;

struct Trie {
	int smallest_index; // smallest index of a value in this sub-trie
	Trie* children[2]; // (either 0 or 1)
	Trie() { smallest_index = INF; children[0] = children[1] = NULL; }

	void insert_value(int value, int index, int bit = 30) {
		// inserts x into the trie
		smallest_index = min(smallest_index, index); // update smallest index in sub-trie

		if (bit == -1) return;
		int value_bit = (value >> bit) & 1;

		// create node if needed
		if (!children[value_bit]) children[value_bit] = new Trie(); 
		
		// recurse from child node
		children[value_bit]->insert_value(value, index, bit - 1); 
	}

	int find_smallest_index(int x, int y, int bit = 30) { 
		// returns smallest index such that P xor x >= y, where P is a element in the trie
	
		if (bit == -1) return INF;
		int current_answer = INF;

		// get bit-th bits of x and y
		int x_bit = (x >> bit) & 1, y_bit = (y >> bit) & 1; 

		for(int p_bit = 0; p_bit <= 1; p_bit++) {
			// not possible (no values like this)
			if (!children[p_bit]) continue;
			
			if ((x_bit ^ p_bit) == y_bit) {
				// possible answer, continue traversing
				if (bit == 0) {
					// reached equality, therefore is an answer
					current_answer = min(
						current_answer, 
						children[p_bit]->smallest_index
					);
				} else {
                    // continue traversing
					current_answer = min(
						current_answer, 
						children[p_bit]->find_smallest_index(x, y, bit - 1)
					);
				}
			}

			if ((x_bit ^ p_bit) > y_bit) {
				// already have P xor x > y, hence all other bits don't matter
	
				// take smallest index in the sub-trie
				current_answer = min(
					current_answer, 
					children[p_bit]->smallest_index); 

				p_bit ^= 1; // continue down other possibility 
			}
		}

		return current_answer;
	}
		
};

int main() {
	int N, X; cin >> N >> X;
	vector<int> seq(N); for(auto& x : seq) cin >> x;

	Trie trie;
	int current_xor = 0; trie.insert_value(current_xor, -1);

	int answer = 0, best_index = -1;
	for(int index = 0; index < N; index++) {
		current_xor ^= seq[index];

		int position = trie.find_smallest_index(current_xor, X); // get best position 

		if (answer < (index - position)) { // check if its a better answer
			answer = (index - position);
			best_index = position + 1; // position is exclusive
		}

		trie.insert_value(current_xor, index);
	}

	cout << best_index + 1 << " " << answer << nl;

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...