-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathxor.cpp
More file actions
155 lines (141 loc) · 4.26 KB
/
xor.cpp
File metadata and controls
155 lines (141 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iostream>
#include <vector>
using namespace std;
/**Note
* Given N positive numbers, and a number m, calculate the number of pairs
* whose result with 'xor' operator greater than m.
*
* Source: 今日头条
*/
/**
* The trie tree Node
*/
struct Node {
struct Node* left;
struct Node* right;
int left_num; // The number of element less than
int right_num; // The number of element greater than
Node(int left_num, int right_num): left(nullptr), right(nullptr), \
left_num(left_num), \
right_num(right_num) {};
};
class Solution {
public:
/**
* The function get the number of pairs
*
* params:
* test: the number list
* m: the threshold
*/
int getNum(vector<int>& test, int m) {
Node* root = new Node(0, 0);
// construct the trie tree
for (auto& ele : test) {
addNode(root, ele, 31);
}
long long result = 0;
// accumulate the pair for each element
for (auto& ele : test) {
searchNode(root, ele, m, 31, result);
}
// each pairs calculate two times, get the half of it
return result / 2;
}
/**
* Search the trie tree to get the number
* Conditions:
* 1: m[pos] = 0, val[pos] = 0, so the right (1) side is ok (add to the
* result), and continue the left (0) side of the node.
* 2: m[pos] = 1, val[pos] = 0, so the left (0) side is invalid, and
* continue the right (1) side
* 3: m[pos] = 0, val[pos] = 1, so the left (0) side is ok (add to the
* result), and continue the right (0) side.
* 4: m[pos] = 1, val[pos] = 1, so the right (1) sid is invalid, and
* continue the left (0) side.
*
* params:
* root: the root of the subtree
* val: current valid value
* pos: the bit pos [31....0]
* result: the accumulate result
*/
void searchNode(Node* root, int val, int m, int pos, long long& result) {
if (pos < 0 || !root) {
return;
}
// get the bit value of m in "pos"
int m_bit = (m & (1 << pos)) == 0? 0 : 1;
// get the bit value of val in "pos"
int val_bit = (val & (1 << pos)) == 0? 0 : 1;
if (val_bit == 0) {
if (m_bit == 0) {
// condition 1
result += root->right_num;
searchNode(root->left, val, m, pos - 1, result);
} else {
// condition 2
searchNode(root->right, val, m, pos - 1, result);
}
} else {
if (m_bit == 0) {
// condition 3
result += root->left_num;
searchNode(root->right, val, m, pos - 1, result);
} else {
// condition 4
searchNode(root->left, val, m, pos - 1, result);
}
}
}
/**
* Construct the trie tree
*
* params:
* root: the root of the subtree
* val: the value need to insert to the trie tree
* pos: the bit pos [31....0]
*/
void addNode(Node* root, int val, int pos) {
if (pos < 0) {
return;
}
// get the bit value of val in "pos"
int tmp = (val & (1 << pos)) == 0? 0 : 1;
if (tmp == 0) {
// insert to the left and increase the count
root->left_num++;
if (!root->left) {
root->left = new Node(0, 0);
}
addNode(root->left, val, pos - 1);
} else {
// insert to the right and increase the count
root->right_num++;
if (!root->right) {
root->right = new Node(0, 0);
}
addNode(root->right, val, pos - 1);
}
}
};
/**
* Input: n, m, and with n number
* Output: the number of pairs which result of 'xor' operator greater than m
*/
int main() {
Solution so;
int n, m, tmp;
vector<int> test;
while (cin >> n) {
// clear the previous input
test.clear();
cin >> m;
while (n-- > 0) {
cin >> tmp;
test.push_back(tmp);
}
cout << so.getNum(test, m) << endl;
}
return 0;
}