#include <iostream> #include <queue> #include <vector> const uint32_t bn = 1e9 + 7; // Duża liczba. const uint32_t pow_2_15 = 32768; void add_edge(std::vector<uint32_t> adj[], uint32_t u, uint32_t v) { // Uwaga. Pozwala dodać wielokrotną krawędź (ale tu takich nie ma). adj[u].push_back(v); adj[v].push_back(u); } //void print_graph(std::vector<uint32_t> adj[], uint32_t V) //{ // for (uint32_t v = 0; v < V; ++v) // { // std::cout << "vertex " << v << " "; // for (uint32_t i = 0; i < adj[v].size(); i++) // std::cout << " -> " << adj[v][i]; // std::cout << "\n"; // } // std::cout << "\n"; //} void check_subgraph(std::vector<uint32_t> adj[], uint8_t c[], uint32_t n, uint32_t v, bool checked[], uint32_t &sub_size, bool &press_works) { // Sprawdza spójny podgraf, zwracając jego rozmiar i to, czy przyciski // zadziałają. std::vector<bool> visited(n, false); std::queue<uint32_t> q; q.push(v); visited[v] = true; sub_size = 1; press_works = false; checked[v] = true; while (!q.empty()) { uint32_t current = q.front(); q.pop(); for (std::vector<uint32_t>::iterator it = adj[current].begin(); it != adj[current].end(); it++) { if (c[*it] == c[current]) press_works = true; if (!visited[*it]) { visited[*it] = true; checked[*it] = true; sub_size++; q.push(*it); } } } } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); uint32_t n, m; std::cin >> n >> m; uint8_t c[n]; bool checked[n]; for (uint32_t i = 0; i < n; ++i) { std::cin >> c[i]; checked[i] = false; } std::vector<uint32_t> adj[n]; for (uint32_t i = 0; i < m; ++i) { uint32_t a, b; std::cin >> a >> b; add_edge(adj, a - 1, b - 1); } // print_graph(adj, n); // Zakładamy, że w każdej spójnej składowej jest co najmniej jedna krawędź, // która łączy dwa wierzchołki o tym samym stanie. W przeciwnym razie // przełączniki nie działają. uint32_t sub_size, press_works_cnt = 0; bool press_works; for (uint32_t i = 0; i < n; i++) { if (!checked[i]) { check_subgraph(adj, c, n, i, checked, sub_size, press_works); if (press_works) press_works_cnt += sub_size; } } uint32_t bits_m_1 = press_works_cnt - 1; uint32_t result = 1; uint32_t div15 = bits_m_1 / 15, mod15 = bits_m_1 % 15; for (int i = 0; i < div15; i++) result = (result * pow_2_15) % bn; for (int i = 0; i < mod15; i++) result = (result * 2) % bn; std::cout << result << "\n"; // system("pause"); return 0; }
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 | #include <iostream> #include <queue> #include <vector> const uint32_t bn = 1e9 + 7; // Duża liczba. const uint32_t pow_2_15 = 32768; void add_edge(std::vector<uint32_t> adj[], uint32_t u, uint32_t v) { // Uwaga. Pozwala dodać wielokrotną krawędź (ale tu takich nie ma). adj[u].push_back(v); adj[v].push_back(u); } //void print_graph(std::vector<uint32_t> adj[], uint32_t V) //{ // for (uint32_t v = 0; v < V; ++v) // { // std::cout << "vertex " << v << " "; // for (uint32_t i = 0; i < adj[v].size(); i++) // std::cout << " -> " << adj[v][i]; // std::cout << "\n"; // } // std::cout << "\n"; //} void check_subgraph(std::vector<uint32_t> adj[], uint8_t c[], uint32_t n, uint32_t v, bool checked[], uint32_t &sub_size, bool &press_works) { // Sprawdza spójny podgraf, zwracając jego rozmiar i to, czy przyciski // zadziałają. std::vector<bool> visited(n, false); std::queue<uint32_t> q; q.push(v); visited[v] = true; sub_size = 1; press_works = false; checked[v] = true; while (!q.empty()) { uint32_t current = q.front(); q.pop(); for (std::vector<uint32_t>::iterator it = adj[current].begin(); it != adj[current].end(); it++) { if (c[*it] == c[current]) press_works = true; if (!visited[*it]) { visited[*it] = true; checked[*it] = true; sub_size++; q.push(*it); } } } } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); uint32_t n, m; std::cin >> n >> m; uint8_t c[n]; bool checked[n]; for (uint32_t i = 0; i < n; ++i) { std::cin >> c[i]; checked[i] = false; } std::vector<uint32_t> adj[n]; for (uint32_t i = 0; i < m; ++i) { uint32_t a, b; std::cin >> a >> b; add_edge(adj, a - 1, b - 1); } // print_graph(adj, n); // Zakładamy, że w każdej spójnej składowej jest co najmniej jedna krawędź, // która łączy dwa wierzchołki o tym samym stanie. W przeciwnym razie // przełączniki nie działają. uint32_t sub_size, press_works_cnt = 0; bool press_works; for (uint32_t i = 0; i < n; i++) { if (!checked[i]) { check_subgraph(adj, c, n, i, checked, sub_size, press_works); if (press_works) press_works_cnt += sub_size; } } uint32_t bits_m_1 = press_works_cnt - 1; uint32_t result = 1; uint32_t div15 = bits_m_1 / 15, mod15 = bits_m_1 % 15; for (int i = 0; i < div15; i++) result = (result * pow_2_15) % bn; for (int i = 0; i < mod15; i++) result = (result * 2) % bn; std::cout << result << "\n"; // system("pause"); return 0; } |