Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <cstdlib> // для функций rand() и srand()
- #include <list>
- #include <random>
- #include <ctime>
- using namespace std;
- const int p = 2 * 1e9 + 11;
- const int c = 3;
- std::random_device rand_dev;
- std::mt19937 generator(rand_dev());
- int rand_int(int min, int max)
- {
- std::uniform_int_distribution<int> distr(min, max);
- return distr(generator);
- }
- long long int uni_hash(long long int a, long long int b, int m, int key)
- {
- return ((a * key + b) % p) % m;
- }
- struct vertex
- {
- bool visited = false;
- vector<struct adj_vertex> adj_list;
- int list_size = 0;
- long long int label = -1;
- };
- struct adj_vertex
- {
- int idx;
- int edge_value;
- };
- class Graph
- {
- vertex* G;
- int size;
- public:
- Graph(int n);
- int get_size();
- void addEdge(int i, int j, int key_idx);
- void print_graph();
- void DFS(int v_idx, int value, bool& flag);
- bool is_correct();
- long long int get_label(int number_vertex);
- };
- Graph::Graph(int n)
- {
- G = new vertex[n];
- size = n;
- }
- long long int Graph::get_label(int number_vertex)
- {
- return G[number_vertex].label;
- }
- int Graph::get_size()
- {
- return this->size;
- }
- void Graph::addEdge(int i, int j, int key_idx)
- {
- if (i < 0 || j < 0)
- {
- cout << "Передана вершина с отриц. индексом - ошибка! \n";
- }
- //cout << "addEdge by :" << i << " " << j << " " << key_idx << endl;
- adj_vertex tmp;
- tmp.idx = j;
- tmp.edge_value = key_idx;
- G[i].adj_list.push_back(tmp);
- tmp.idx = i;
- G[j].adj_list.push_back(tmp);
- G[i].list_size++;
- G[j].list_size++;
- }
- void Graph::print_graph()
- {
- cout << "\n print:" << endl;
- for (int i = 0; i < size; i++)
- {
- cout << "visited = " << G[i].visited << "; i= " << i << "; ";
- cout << " label = " << G[i].label << " : ";
- int size = G[i].adj_list.size();
- cout << "idx =: ";
- for (int j = 0; j < size; ++j)
- {
- cout << G[i].adj_list[j].idx << " ";
- }
- cout << "; edge_value =: ";
- for (int j = 0; j < size; ++j)
- {
- cout << G[i].adj_list[j].edge_value << " ";
- }
- cout << endl;
- }
- }
- void Graph::DFS(int v_idx, int value, bool& flag) //мб лучше не по указателю по индексу
- {
- if (flag)
- {
- G[v_idx].visited = true;
- G[v_idx].label = value;
- vertex u;
- vector<struct adj_vertex> curr_list = G[v_idx].adj_list;
- int u_idx, val, edge_value;
- for (int i = 0; i < G[v_idx].list_size; ++i)
- {
- u_idx = curr_list[i].idx;
- u = G[u_idx];
- edge_value = curr_list[i].edge_value;
- if (!(u.visited))
- {
- val = edge_value - value;
- DFS(u_idx, val, flag);
- }
- if ( ( (G[u_idx].label + G[v_idx].label) % (this->size) ) != edge_value)
- {
- flag = false;
- }
- }
- }
- }
- bool Graph::is_correct()
- {
- bool flag = true;
- for (int i = 0; i < this->size; ++i)
- {
- if (!G[i].visited)
- DFS(i, 0, flag);
- if (!flag)
- return false;
- }
- return true;
- }
- class FixedSet
- {
- int count_numbers;
- int size;
- long long int a1, a2, b1, b2;
- vector<int> table;
- vector<int> A;
- public:
- FixedSet();
- void Initialize(const vector<int>& numbers);
- bool Contains(int number) const;
- void print();
- };
- FixedSet::FixedSet()
- {
- this->count_numbers = 0;
- this->size = 0;
- }
- void FixedSet::Initialize(const vector<int>& numbers)
- {
- this->count_numbers = numbers.size(); //Число чисел для хранения
- this->size = (this->count_numbers) * c; //Размер графа
- int n = this->count_numbers;
- int m = this->size;
- for (int i =0; i < n; ++i)
- table.push_back(numbers[i]);
- cout << "n,m,p = " << n << " " << m << " " << p << endl;
- this->table.resize(m);
- this->A.resize(m);
- int a, b;
- long long int alpha_k, beta_k;
- bool flag = false;
- cout << "Сейчас зайду в вайл" << endl;
- while (!flag)
- {
- cout << "Зашёл" << endl;
- Graph g(m);
- a1 = rand_int(1, p - 1);
- b1 = rand_int(0, p - 1);
- a2 = rand_int(1, p - 1);
- b2 = rand_int(0, p - 1);
- cout << "Сгенерил а б а б " << a1 << " " << b1 << " " << a2 << " " << b1 << endl;
- for (int i = 0; i < n; ++i)
- {
- alpha_k = uni_hash(a1, b1, m, numbers[i]);
- beta_k = uni_hash(a2, b2, m, numbers[i]);
- cout << "i: " << i << " alpha_k, beta_k : " << alpha_k << " " << beta_k << endl;
- g.addEdge(alpha_k, beta_k, i);
- }
- //Граф построен, осталось проверить что он корректный. Вызову DFS и он ответит yes or no
- cout << "Граф построен, осталось проверить что он корректный" << endl;
- //g.print_graph();
- if (g.is_correct())
- {
- cout << "correct!" << endl;
- flag = true;
- this->a1 = a1;
- this->a2 = a2;
- this->b1 = b1;
- this->b2 = b2;
- g.print_graph();
- cout << "\n запишу А" << endl;
- for (int i = 0; i < m; ++i)
- {
- this->A[i] = g.get_label(i);
- //cout << "A[" << i << "] = " << this->A[i] << "; ";
- }
- }
- }
- }
- bool FixedSet::Contains(int number) const
- {
- int m = this->size;
- int hash1 = uni_hash(this->a1, this->b1, m, number);
- int hash2 = uni_hash(this->a2, this->b2, m, number);
- int idx = (A[hash1] + A[hash2]) % m;
- if (0 <= idx < m)
- return (this->table[idx] == number);
- return false;
- }
- int main()
- {
- FixedSet Fix_set;
- std::vector<int> F;
- long long int req;
- int a, n, count_of_req;
- std::cin >> n;
- for (int i = 0; i < n; ++i)
- {
- std::cin >> a;
- F.push_back(a);
- }
- std::cin >> count_of_req;
- Fix_set.Initialize(F);
- for (int i = 0; i < count_of_req; ++i)
- {
- std::cin >> req;
- if (Fix_set.Contains(req))
- std::cout << "Yes" << std::endl;
- else
- std::cout << "No" << std::endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment