#include <iostream> #include <vector> #include <queue> using namespace std; const int MOD = 1000000007; long long power(long long b, int e) { if (e == 0) return 1; long long half = power(b, e/2); half = (half * half) % MOD; if (e%2) return (b * half) % MOD; else return half; } long long inv(long long x) { return power(x, MOD-2); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<bool> B(n); for (int i=0; i<n; i++) { int x; cin >> x; B[i] = (x==1); } vector<vector<int>> G(n); for (int i=0; i<m; i++) { int x, y; cin >> x >> y; G[x-1].push_back(y-1); G[y-1].push_back(x-1); } // prepare factorial buffer vector<long long> Fact(n+1), InvFact(n+1); Fact[0] = Fact[1] = InvFact[0] = InvFact[1] = 1; for (int i=2; i<=n; i++) { Fact[i] = (Fact[i-1] * i) % MOD; InvFact[i] = inv(Fact[i]); } auto binom = [&](int n, int k) -> long long { return (((Fact[n] * InvFact[k]) % MOD) * InvFact[n-k]) % MOD; }; vector<int> Col(n, -1); long long result = 1; for (int comp_root=0; comp_root<n; comp_root++) if (Col[comp_root] == -1) { // 2-coloring queue<int>Q; bool bipartite = true; Col[comp_root] = 0; int cntAll[2] = {1, 0}; int cntLit[2] = {int(B[comp_root]), 0}; Q.push(comp_root); while (!Q.empty()) { int v = Q.front(); Q.pop(); for (int nei : G[v]) if (Col[nei] == -1) { Col[nei] = 1-Col[v]; cntAll[Col[nei]]++; cntLit[Col[nei]]+=int(B[nei]); Q.push(nei); } else if (Col[nei] == Col[v]) bipartite = false; } // if component is bipartite if (bipartite) { long long local_result = 0; int delta = cntLit[0]-cntLit[1]; if (delta<0) { delta = -delta; swap(cntAll[0], cntAll[1]); } for (int l=delta,r=0; l<=cntAll[0] && r<=cntAll[1]; l++,r++) local_result = (local_result + binom(cntAll[0], l) * binom(cntAll[1], r)) % MOD; result = (result * local_result) % MOD; } // if it has an odd cycle else result = (result * power(2, cntAll[0]+cntAll[1]-1)) % MOD; } cout << result << '\n'; 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 | #include <iostream> #include <vector> #include <queue> using namespace std; const int MOD = 1000000007; long long power(long long b, int e) { if (e == 0) return 1; long long half = power(b, e/2); half = (half * half) % MOD; if (e%2) return (b * half) % MOD; else return half; } long long inv(long long x) { return power(x, MOD-2); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<bool> B(n); for (int i=0; i<n; i++) { int x; cin >> x; B[i] = (x==1); } vector<vector<int>> G(n); for (int i=0; i<m; i++) { int x, y; cin >> x >> y; G[x-1].push_back(y-1); G[y-1].push_back(x-1); } // prepare factorial buffer vector<long long> Fact(n+1), InvFact(n+1); Fact[0] = Fact[1] = InvFact[0] = InvFact[1] = 1; for (int i=2; i<=n; i++) { Fact[i] = (Fact[i-1] * i) % MOD; InvFact[i] = inv(Fact[i]); } auto binom = [&](int n, int k) -> long long { return (((Fact[n] * InvFact[k]) % MOD) * InvFact[n-k]) % MOD; }; vector<int> Col(n, -1); long long result = 1; for (int comp_root=0; comp_root<n; comp_root++) if (Col[comp_root] == -1) { // 2-coloring queue<int>Q; bool bipartite = true; Col[comp_root] = 0; int cntAll[2] = {1, 0}; int cntLit[2] = {int(B[comp_root]), 0}; Q.push(comp_root); while (!Q.empty()) { int v = Q.front(); Q.pop(); for (int nei : G[v]) if (Col[nei] == -1) { Col[nei] = 1-Col[v]; cntAll[Col[nei]]++; cntLit[Col[nei]]+=int(B[nei]); Q.push(nei); } else if (Col[nei] == Col[v]) bipartite = false; } // if component is bipartite if (bipartite) { long long local_result = 0; int delta = cntLit[0]-cntLit[1]; if (delta<0) { delta = -delta; swap(cntAll[0], cntAll[1]); } for (int l=delta,r=0; l<=cntAll[0] && r<=cntAll[1]; l++,r++) local_result = (local_result + binom(cntAll[0], l) * binom(cntAll[1], r)) % MOD; result = (result * local_result) % MOD; } // if it has an odd cycle else result = (result * power(2, cntAll[0]+cntAll[1]-1)) % MOD; } cout << result << '\n'; return 0; } |