-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetstack.cc
More file actions
129 lines (94 loc) · 2.6 KB
/
setstack.cc
File metadata and controls
129 lines (94 loc) · 2.6 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
// William Sjöblom
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <cstdio>
#include <map>
#include <algorithm>
#include <iterator>
struct Set;
static std::vector<Set> sets { };
static std::map<Set, size_t> lookup { };
struct Set {
std::set<size_t> children;
size_t key() {
auto it = lookup.find(*this);
if (it != lookup.end()) return it->second;
sets.push_back(*this);
lookup[*this] = sets.size() - 1;
return sets.size() - 1;
}
const bool operator<(const Set& other) const {
return children < other.children;
}
};
Set& find(size_t key) {
return sets[key];
}
using Stack = std::stack<size_t>;
/**
* Push empty set.
*/
void push(Stack& stack) {
Set empty;
stack.push(empty.key());
}
/**
* Duplicate the top-most set.
*/
void dup(Stack& stack) {
stack.push(stack.top());
}
/**
* Push the union of the two top-most sets.
*/
void uni(Stack& stack) {
Set& a = find(stack.top()); stack.pop();
Set& b = find(stack.top()); stack.pop();
Set result;
std::set_union(a.children.begin(), a.children.end(),
b.children.begin(), b.children.end(),
std::inserter(result.children, result.children.end()));
stack.push(result.key());
}
void intersect(Stack& stack) {
Set& a = find(stack.top()); stack.pop();
Set& b = find(stack.top()); stack.pop();
Set result;
std::set_intersection(a.children.begin(), a.children.end(),
b.children.begin(), b.children.end(),
std::inserter(result.children, result.children.end()));
stack.push(result.key());
}
void add(Stack& stack) {
Set& a = find(stack.top()); stack.pop();
Set b = find(stack.top()); stack.pop();
b.children.insert(a.key());
stack.push(b.key());
}
int main() {
int test_cases;
scanf("%d", &test_cases);
while (test_cases--) {
sets.clear();
lookup.clear();
int op_count;
scanf("%d", &op_count);
Stack stack;
while (op_count--) {
char s[10];
scanf("%10s", s);
std::string op { s };
if (op == "PUSH") push(stack);
else if (op == "DUP") dup(stack);
else if (op == "UNION") uni(stack);
else if (op == "INTERSECT") intersect(stack);
else if (op == "ADD") add(stack);
else printf("UNKNOWN COMMAND: %s\n", s);
Set& top = find(stack.top());
printf("%lu\n", top.children.size());
}
printf("***\n");
}
}