#include <bits/stdc++.h> using namespace std; using ll = long long; int n, m; ll P = 1000000007; std::vector<int> values; std::vector<std::vector<int>> E; std::vector<bool> visited; std::vector<bool> bipartite_division; void dfs(int x, int *bipartite_count, int *bipartite_sums, bool component, bool& not_bipartite) { visited[x] = true; bipartite_division[x] = component; bipartite_count[component]++; bipartite_sums[component] += values[x]; for(int child : E[x]) { if(visited[child]) { if(bipartite_division[x] == bipartite_division[child]) { not_bipartite = true; } continue; } dfs(child, bipartite_count, bipartite_sums, !component, not_bipartite); } } ll fastexp(ll base, ll exp, ll mod) { if(exp == 0) return 1; if(exp % 2 == 0) { ll t = fastexp(base, exp / 2, mod); return (t * t) % mod; } else { return (base * fastexp(base, exp - 1, mod)) % mod; } } ll inverse_mod_prime(ll a, ll p) { return fastexp(a, p - 2, p); } ll factorials[500000]; void init() { factorials[0] = 1; for(ll i = 1; i < 500000; i++) { factorials[i] = (i * factorials[i - 1]) % P; } } ll binomial_coef_mod_P(int n, int k) { return factorials[n] * inverse_mod_prime(factorials[k], P) % P * inverse_mod_prime(factorials[n - k], P) % P; } int main() { init(); cin >> n >> m; values = std::vector<int>(n + 1); visited = std::vector<bool>(n + 1, false); bipartite_division = std::vector<bool>(n + 1); for(int i = 1; i <= n; i++) { cin >> values[i]; } E = std::vector<std::vector<int>>(n + 1); for(int i = 1; i <= m; i++) { int u, v; cin >> u >> v; E[u].push_back(v); E[v].push_back(u); } ll total = 1; for(int x = 1; x <= n; x++) { if(visited[x]) { continue; } int bipartite_count[2] = {0, 0}; int bipartite_sums[2] = {0, 0}; bool not_bipartite = false; dfs(x, bipartite_count, bipartite_sums, false, not_bipartite); if(not_bipartite) { ll component_size = bipartite_count[0] + bipartite_count[1]; ll contribution = fastexp(2, component_size - 1, P); total = total * contribution % P; //std::cerr << "component of size " << bipartite_count[0] + bipartite_count[1] << "\n"; //std::cerr << "contribution = " << contribution << "\n"; } else { ll contribution = binomial_coef_mod_P(bipartite_count[0] + bipartite_count[1], bipartite_sums[0] - bipartite_sums[1] + bipartite_count[1]); total = total * contribution % P; //std::cerr << "bipartite component of size " << bipartite_count[0] << " " << bipartite_count[1] // << ", sums " << bipartite_sums[0] << " " << bipartite_sums[1] << "\n"; //std::cerr << "contribution = " << contribution << "\n"; } } std::cout << total << "\n"; }
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 | #include <bits/stdc++.h> using namespace std; using ll = long long; int n, m; ll P = 1000000007; std::vector<int> values; std::vector<std::vector<int>> E; std::vector<bool> visited; std::vector<bool> bipartite_division; void dfs(int x, int *bipartite_count, int *bipartite_sums, bool component, bool& not_bipartite) { visited[x] = true; bipartite_division[x] = component; bipartite_count[component]++; bipartite_sums[component] += values[x]; for(int child : E[x]) { if(visited[child]) { if(bipartite_division[x] == bipartite_division[child]) { not_bipartite = true; } continue; } dfs(child, bipartite_count, bipartite_sums, !component, not_bipartite); } } ll fastexp(ll base, ll exp, ll mod) { if(exp == 0) return 1; if(exp % 2 == 0) { ll t = fastexp(base, exp / 2, mod); return (t * t) % mod; } else { return (base * fastexp(base, exp - 1, mod)) % mod; } } ll inverse_mod_prime(ll a, ll p) { return fastexp(a, p - 2, p); } ll factorials[500000]; void init() { factorials[0] = 1; for(ll i = 1; i < 500000; i++) { factorials[i] = (i * factorials[i - 1]) % P; } } ll binomial_coef_mod_P(int n, int k) { return factorials[n] * inverse_mod_prime(factorials[k], P) % P * inverse_mod_prime(factorials[n - k], P) % P; } int main() { init(); cin >> n >> m; values = std::vector<int>(n + 1); visited = std::vector<bool>(n + 1, false); bipartite_division = std::vector<bool>(n + 1); for(int i = 1; i <= n; i++) { cin >> values[i]; } E = std::vector<std::vector<int>>(n + 1); for(int i = 1; i <= m; i++) { int u, v; cin >> u >> v; E[u].push_back(v); E[v].push_back(u); } ll total = 1; for(int x = 1; x <= n; x++) { if(visited[x]) { continue; } int bipartite_count[2] = {0, 0}; int bipartite_sums[2] = {0, 0}; bool not_bipartite = false; dfs(x, bipartite_count, bipartite_sums, false, not_bipartite); if(not_bipartite) { ll component_size = bipartite_count[0] + bipartite_count[1]; ll contribution = fastexp(2, component_size - 1, P); total = total * contribution % P; //std::cerr << "component of size " << bipartite_count[0] + bipartite_count[1] << "\n"; //std::cerr << "contribution = " << contribution << "\n"; } else { ll contribution = binomial_coef_mod_P(bipartite_count[0] + bipartite_count[1], bipartite_sums[0] - bipartite_sums[1] + bipartite_count[1]); total = total * contribution % P; //std::cerr << "bipartite component of size " << bipartite_count[0] << " " << bipartite_count[1] // << ", sums " << bipartite_sums[0] << " " << bipartite_sums[1] << "\n"; //std::cerr << "contribution = " << contribution << "\n"; } } std::cout << total << "\n"; } |