Maximum XOR is faster than just using XOR

Given the number N and an array of integers (all nos less than 2 ^ 15). (A - array size 100000)
Find the maximum value of XOR N and the integer from the array.

Q - there are no requests (50,000) and start, stop is the range in the array.

Input:
AQ
a1 a2 a3 ...
N start-stop

Conclusion: The
maximum value of XOR N and an integer in the array with the specified range.

For example: Login / 15 2 (2 no requests)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
10 6 10 (Request 1)
10 6 10 (Request 2)

Output:
13
13

Code:

for(int i=start-1;i<stop;i++){
int t =no[i]^a;
if(maxxor<t)
     maxxor=t;
}
cout << maxxor <<endl;

10-100 . . , -.

2x - 3 ? .

+2
5

.

N: a [0], a [1],..., a [15], , N = 13 = 0000000 00001101 ( ), a [0] = a [1 ] =... a [11] = 0, a [12] = 1, a [13] = 1, a [14] = 0, a [15] = 1.

: a [0] == 1, , . a [0] == 0, . , . , . , . . . a [0] == 1, a [1] == 0, , , , , , , 01. , , , 11. ...

, : , ... , ?

: Construct trie . node , ( ). . , , , node.

O (lg ^ 2 N), .

, , :

#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

class TrieNode {
 public:
  TrieNode* next[2];
  vector<int> positions;

  TrieNode() {
    next[0] = next[1] = NULL;
  }

  bool HasNumberInRange(int start, int stop) {
    vector<int>::iterator it = lower_bound(
        positions.begin(), positions.end(), start);
    if (it == positions.end()) return false;
    return *it < stop;
  }
};

void AddNumberToTrie(int number, int index, TrieNode* base) {
  TrieNode* cur = base;
  // Go through all binary digits from most significant
  for (int i = 14; i >= 0; i--) {
    int digit = 0;
    if ((number & (1 << i)) != 0) digit = 1;
    cur->positions.push_back(index);
    if (cur->next[digit] == NULL) {
      cur->next[digit] = new TrieNode;
    }
    cur = cur->next[digit];
  }
  cur->positions.push_back(index);
}

int FindBestNumber(int a, int start, int stop, TrieNode* base) {
  int best_num = 0;
  TrieNode* cur = base;
  for (int i = 14; i >= 0; i--) {
    int digit = 1;
    if ((a & (1 << i)) != 0) digit = 0;
    if (cur->next[digit] == NULL || 
        !cur->next[digit]->HasNumberInRange(start, stop))
      digit = 1 - digit;
    best_num *= 2;
    best_num += digit;
    cur = cur->next[digit];
  }
  return best_num;
}


int main() {
  int n; scanf("%d", &n);
  int q; scanf("%d", &q);
  TrieNode base;
  for (int i = 0; i < n; i++) {
    int x; scanf("%d", &x);
    AddNumberToTrie(x, i, &base);
  }

  for (int i = 0; i < q; i++) {
    int a, start, stop;
    // Finds biggest i, such that start <= i < stop and XOR with a is as big as possible
    // Base index is 0
    scanf("%d %d %d", &a, &start, &stop);
    printf("%d\n", FindBestNumber(a, start, stop, &base)^a);
  }
}
+5

, :

15, , , ( - 0, - 1).

. 0 1 4 7:

    /   \
  /      /\
/ \     /  \
0 1    4    7

: N = n_1 n_2 n_3... n_15 n_1 - N, n_2 ... , , n_i = 0 ( - node), , . , .

:

, .

, , , .

+1

(O(start-stop) O(N) ). , , , , .

, , , .


:

, , .

, , . start end .

, , - , .

, , , .

+1

, O (AlogM) . O (log 2 M) . M - , 2 ^ 15 .


1st..Nth number, (Tree Group 1)
1-.. (A/2) - , (A/2) - ., ( 2)
1-.. (A/4) - , (A/4) th.. (A/2) - , (A/2) th.. (3A/4) th, (3A/3) th.. Ath, ( 3)
......., ( 4)
.......,
......., (Tree Group logA)
trie . 2M . O (AlogM) . , x , logM * x node. .

( 2 logA), . XOR O (logM) ( ). O (logA * logM).

? 1 , 0 N, - 0. , , - .

+1

, , , .

int maxXor(int l, int r) {
    int highest_xor = 0;
    int base = l;
    int tbase = l;
    int val = 0;
    int variance = 0;
    do
    {
        while(tbase + variance <= r)
        {
            val = base ^ tbase + variance;
            if(val > highest_xor)
            {
                highest_xor = val;
            }
            variance += 1;
        }
        base +=1;
        variance = 0;
    }while(base <= r);
    return highest_xor;
}
0

Source: https://habr.com/ru/post/1675949/


All Articles