-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtrie.cpp
109 lines (101 loc) · 2.29 KB
/
trie.cpp
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
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define SYNC std::ios_base::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);
#define FRE freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
typedef long double ld;
typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
#define rep(i,l,r) for (int i = (l); i < (r); i++)
#define here cout << " Hey!!\n";
#define pb push_back
#define F first
#define S second
#define all(v) (v).begin(),(v).end()
#define sz(a) (int)((a).size())
#define sq(x) ((x)*(x))
const int N = 1e5+5;
int n, k;
int v[N];
struct node
{
int freq;
node* nxt[2];
node()
{
nxt[0] = nxt[1] = nullptr;
freq = 0;
}
};
node* root;
void insert(int x) {
node* cur = root;
for (int i = 30; i >= 0; i--) {
cur->freq = cur->freq + 1;
int now = (x >> i)&1;
if (cur->nxt[now] == nullptr) {
cur->nxt[now] = new node;
}
cur = cur->nxt[now];
}
cur->freq++;
}
void del(int x) {
node* cur = root;
for (int i = 30; i >= 0; i--) {
cur->freq = cur->freq - 1;
int now = (x >> i)&1;
if (cur->nxt[now] == nullptr) {
cur->nxt[now] = new node;
}
cur = cur->nxt[now];
}
if (cur->freq)
cur->freq--;
}
int get_cnt(int val) {
node* cur = root;
long long res = 0;
for (int i = 0; i < n; i++) {
cur = root;
for (int j = 30; j >= 0; j--) {
if (cur == nullptr or cur->freq == 0) break;
int b_now = ((v[i]>>j)&1), val_now = ((val>>j)&1);
if (cur->nxt[b_now] != nullptr && val_now) {
res += (cur->nxt[b_now])->freq;
}
cur = cur->nxt[b_now ^ val_now];
}
}
return (res - n) / 2;
}
void solve() {
cin >> n >> k;
rep(i,0,n) {
cin >> v[i];
insert(v[i]);
}
int lo = 0, hi = (1LL<<31) - 1;
while (lo < hi) {
int mid = (lo + hi + 1) / 2;
if (get_cnt(mid) < k)
lo = mid;
else
hi = mid - 1;
}
cout << lo << '\n';
rep(i,0,n)
del(v[i]);
}
int32_t main()
{
SYNC
root = new node;
int T; cin >> T;
while(T--) {
solve();
}
return 0;
}