#pragma once #include #include class Set { public: explicit Set(const std::vector& a = {}); Set Union(const Set&) const; Set Difference(const Set&) const; Set SymmetricDifference(const Set&) const; Set Intersection(const Set&) const; void Add(int64_t); void Remove(int64_t); bool Contains(int64_t) const; std::vector Data() const; std::vector c; }; const int n = 1000007; void Set::Add(int64_t val) { int i = (val * 3 + 11) % c.size(); while (c[i] != -1 && c[i] != val) { i = (i + 17) % c.size(); } c[i] = val; } void Set::Remove(int64_t val) { int i = (val * 3 + 11) % c.size(); while (c[i] != -1 && c[i] != val) { i = (i + 17) % c.size(); } if (c[i] == val) { c[i] = -2; } } bool Set::Contains(int64_t val) const { int i = (val * 3 + 11) % c.size(); while (c[i] != -1 && c[i] != val) { i = (i + 17) % c.size(); } return (c[i] == val); } Set::Set(const std::vector& a) { c.assign(n, -1); for (int i = 0; i < a.size(); i++) Add(a[i]); } Set Set::Union(const Set& b) const { Set new_set; for (int i = 0; i < n; i++) { if (c[i] >= 0) new_set.Add(c[i]); if (b.c[i] >= 0) new_set.Add(b.c[i]); } return new_set; } Set Set::Intersection(const Set& b) const { Set new_set; for (int i = 0; i < n; i++) { if (c[i] >= 0 && b.Contains(c[i])) new_set.Add(c[i]); } return new_set; } Set Set::Difference(const Set& b) const { Set new_set; for (int i = 0; i < n; i++) { if (c[i] >= 0 && !(b.Contains(c[i]))) new_set.Add(c[i]); } return new_set; } Set Set::SymmetricDifference(const Set& b) const { Set new_set; for (int i = 0; i < n; i++) { if (c[i] >= 0 && !(b.Contains(c[i]))) new_set.Add(c[i]); if (b.c[i] >= 0 && !(Contains(b.c[i]))) new_set.Add(b.c[i]); } return new_set; } std::vector Set::Data() const { std::vector ans; for (int i = 0; i < n; i++) { if (c[i] >= 0) ans.push_back(c[i]); } return ans; }