Skip to content

Commit 42836d3

Browse files
authored
[20251124] BOJ / P3 / XOR 자료구조 / 권혁준
1 parent 46b86ca commit 42836d3

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
```cpp
2+
#include <bits/stdc++.h>
3+
using namespace std;
4+
5+
class Node {
6+
public:
7+
int cnt;
8+
Node *left, *right; // left = 1, right = 0
9+
10+
Node() {
11+
cnt = 0;
12+
left = nullptr;
13+
right = nullptr;
14+
}
15+
};
16+
17+
class Trie {
18+
Node *root;
19+
20+
public:
21+
Trie() {
22+
root = new Node();
23+
}
24+
25+
void insert(int x) {
26+
Node *now = root;
27+
for(int dep=25;--dep>=0;) {
28+
int bit = x & (1<<dep);
29+
if(bit) {
30+
if(now->left == nullptr) now->left = new Node();
31+
now = now->left;
32+
}
33+
else {
34+
if(now->right == nullptr) now->right = new Node();
35+
now = now->right;
36+
}
37+
now->cnt++;
38+
}
39+
}
40+
41+
int find(int x, int tar) {
42+
int ret = 0;
43+
Node *now = root;
44+
for(int dep=25;--dep>=0;) {
45+
int bit = x & (1<<dep) ? 1 : 0;
46+
int need = bit ^ tar;
47+
int res = 0;
48+
if(need) {
49+
if(now->left == nullptr) now = now->right;
50+
else now = now->left, res = (1<<dep);
51+
}
52+
else {
53+
if(now->right == nullptr) now = now->left, res = (1<<dep);
54+
else now = now->right;
55+
}
56+
ret |= res;
57+
}
58+
return x^ret;
59+
}
60+
61+
int find_min(int x) {
62+
return find(x, 0);
63+
}
64+
65+
int find_max(int x) {
66+
return find(x, 1);
67+
}
68+
69+
void remove(int x) {
70+
Node *now = root;
71+
stack<pair<Node *, char>> st;
72+
st.emplace(now, 'L');
73+
for(int dep=25;--dep>=0;) {
74+
int bit = x & (1<<dep);
75+
if(bit) {
76+
now = now->left;
77+
st.emplace(now, 'L');
78+
}
79+
else {
80+
now = now->right;
81+
st.emplace(now, 'R');
82+
}
83+
}
84+
bool l = 0, r = 0;
85+
while(!st.empty()) {
86+
auto cur = st.top(); st.pop();
87+
if(l) cur.first->left = nullptr;
88+
if(r) cur.first->right = nullptr;
89+
l = 0, r = 0;
90+
if(!--cur.first->cnt) {
91+
cur.first = nullptr;
92+
if(cur.second == 'L') l = 1, r = 0;
93+
else l = 0, r = 1;
94+
}
95+
}
96+
}
97+
};
98+
99+
Trie *trie;
100+
set<int> s;
101+
102+
int add(int x) {
103+
if(!s.count(x)) {
104+
s.insert(x);
105+
trie->insert(x);
106+
}
107+
return s.size();
108+
}
109+
110+
int remove_min() {
111+
if(s.empty()) return -1;
112+
int x = *s.begin();
113+
trie->remove(x);
114+
s.erase(x);
115+
return x;
116+
}
117+
118+
int remove_max() {
119+
if(s.empty()) return -1;
120+
int x = *s.rbegin();
121+
trie->remove(x);
122+
s.erase(x);
123+
return x;
124+
}
125+
126+
int main(){
127+
cin.tie(0)->sync_with_stdio(0);
128+
129+
130+
int T;
131+
for(cin>>T;T--;) {
132+
int N, Q;
133+
cin>>N>>Q;
134+
trie = new Trie();
135+
s = set<int>();
136+
137+
for(int i=0,x;i<N;i++) {
138+
cin>>x;
139+
add(x);
140+
}
141+
142+
for(int o,x;Q--;) {
143+
int ret = -1;
144+
cin>>o;
145+
if(o >= 4) {
146+
if(o == 4) ret = remove_min();
147+
else ret = remove_max();
148+
}
149+
else {
150+
cin>>x;
151+
if(o == 1) ret = trie->find_min(x);
152+
else if(o == 2) ret = trie->find_max(x);
153+
else ret = add(x);
154+
}
155+
156+
cout<<ret<<'\n';
157+
}
158+
}
159+
160+
}
161+
```

0 commit comments

Comments
 (0)