#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"; } |
English