Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- void Configure()
- {
- std::cin.tie(nullptr);
- std::ios_base::sync_with_stdio(false);
- }
- long long sqr(long long number)
- {
- return number * number;
- }
- class SquareHashTable
- {
- int numbers_count;
- std::vector<int> table;
- long long prime = 4000000007;
- long long first_coefficient, second_coefficient;
- int absent_number = 4294979831;
- public:
- SquareHashTable()
- {
- }
- void Initialize(std::vector<int> & numbers)
- {
- numbers_count = static_cast<int>(numbers.size());
- if (numbers_count <= 0)
- {
- return;
- }
- while (1 > 0)
- {
- bool necessary_to_repeat = false;
- table = std::vector<int>(numbers_count * numbers_count, absent_number);
- first_coefficient = ((long long)rand() * rand()) % prime;
- second_coefficient = ((long long)rand() * rand()) % prime;
- for (int i = 0; i < static_cast<int>(numbers.size()); ++i)
- {
- int current_number = numbers[i];
- long long new_hash = compute_hash(current_number);
- if (table[new_hash] != absent_number)
- {
- necessary_to_repeat = true;
- break;
- }
- table[new_hash] = current_number;
- }
- if (!necessary_to_repeat)
- {
- break;
- }
- }
- }
- bool Contains(const int & number) const
- {
- if (static_cast<int>(table.size()) <= 0)
- {
- return false;
- }
- long long hash = compute_hash(number);
- return table[hash] == number;
- }
- private:
- long long compute_hash(int number) const
- {
- return (first_coefficient * (number + 1000000000) + second_coefficient)
- % prime % numbers_count;
- }
- };
- class FixedSet
- {
- int groups_count;
- long long prime = 4294979831;
- std::vector<SquareHashTable> table;
- long long first_coefficient;
- long long second_coefficient;
- public:
- FixedSet()
- {
- }
- void Initialize(const std::vector<int> & numbers)
- {
- groups_count = static_cast<int>(numbers.size());
- if (groups_count <= 0)
- {
- return;
- }
- std::vector<std::vector<int>> groups;
- generate_groups(numbers, &groups);
- generate_square_hash_tables(groups);
- }
- bool Contains(const int & number) const
- {
- if (groups_count <= 0)
- {
- return false;
- }
- long long hash = compute_hash(number);
- return table[hash].Contains(number);
- }
- private:
- void generate_square_hash_tables(std::vector<std::vector<int>> & groups)
- {
- for (int i = 0; i < static_cast<int>(groups.size()); ++i)
- {
- SquareHashTable hashTable;
- hashTable.Initialize(groups[i]);
- table.push_back(hashTable);
- }
- }
- void generate_groups(const std::vector<int> & numbers, std::vector<std::vector<int>> * groups)
- {
- do
- {
- (*groups) = std::vector<std::vector<int >> (static_cast<int>(
- numbers.size()), std::vector<int>());
- first_coefficient = ((long long)rand() * rand()) % prime;
- second_coefficient = ((long long)rand() * rand()) % prime;
- for (int i = 0; i < groups_count; ++i)
- {
- int current_element = numbers[i];
- long long new_element_hash = compute_hash(current_element);
- groups->at(new_element_hash).push_back(current_element);
- }
- } while (groups_powers_squares_sum(groups) > 10 * groups_count);
- }
- static long long groups_powers_squares_sum(std::vector<std::vector<int>> * groups)
- {
- long long sum = 0;
- for (int i = 0; i < static_cast<int>(groups->size()); ++i)
- {
- sum += sqr(static_cast<long long>(groups->at(i).size()));
- }
- return sum;
- }
- long long compute_hash(int number) const
- {
- long long sum = first_coefficient * (number + 1000000000) + second_coefficient;
- long long first_mod = sum % prime;
- long long second_mod = first_mod % groups_count;
- return second_mod;
- }
- };
- void Input(std::vector<int> * numbers, std::vector<int> * requests)
- {
- int numbers_count;
- std::cin >> numbers_count;
- for (int i = 0; i < numbers_count; ++i)
- {
- int new_number;
- std::cin >> new_number;
- numbers->push_back(new_number);
- }
- int requests_count;
- std::cin >> requests_count;
- for (int i = 0; i < requests_count; ++i)
- {
- int new_request;
- std::cin >> new_request;
- requests->push_back(new_request);
- }
- }
- void Solve(std::vector<int> & numbers, std::vector<int> & requests, std::vector<bool> * responses)
- {
- FixedSet fixedSet = FixedSet();
- fixedSet.Initialize(numbers);
- for (auto request : requests)
- {
- responses->push_back(fixedSet.Contains(request));
- }
- }
- void Output(std::vector<bool> & responses)
- {
- for (int i = 0; i < static_cast<int>(responses.size()); ++i)
- {
- std::cout << (responses[i] ? "Yes" : "No") << "\n";
- }
- }
- int main()
- {
- Configure();
- std::vector<int> numbers, requests;
- Input(&numbers, &requests);
- std::vector<bool> responses;
- Solve(numbers, requests, &responses);
- Output(responses);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement