#include <bits/stdc++.h> #pragma GCC optimize("O3", "unroll-loops") #define pb emplace_back #define ins insert #define mp make_pair #define ssize(x) (int)x.size() #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define pii pair <int, int> #define pll pair <ll, ll> #define pld pair <ld, ld> #define st first #define nd second using namespace std; using ll = int_fast64_t; // using lll = __int128_t; using ld = long double; const int oo = 1e9 + 7; const ll ool = 1e18; const int mod = 1e9 + 7; struct DSU{ vector <int> rep, sz; DSU(int n){ rep.resize(n); sz.assign(n, 1); iota(all(rep), 0); } int find(int x){ if(rep[x] == x) return x; return rep[x] = find(rep[x]); } int get(int x){ return sz[find(x)]; } bool same(int a, int b){ return find(a) == find(b); } void un(int a, int b){ sz[find(a)] += sz[find(b)]; rep[find(b)] = find(a); } }; void solve(){ int n, m; cin >> n >> m; vector <int> tab(n); for(auto &i: tab) cin >> i; vector <vector<int>> g(n); DSU T(n); while(m --){ int a, b; cin >> a >> b; -- a; -- b; g[a].pb(b); g[b].pb(a); if(!T.same(a, b)) T.un(a, b); } vector <vector<int>> wh(n); for(int i = 0; i < n; i ++) wh[T.find(i)].pb(i); vector <bool> is(n), vis(n), col(n); function<void(int, bool)> dfs = [&](int v, bool x){ vis[v] = 1; col[v] = x; for(auto u: g[v]){ if(!vis[u]) dfs(u, !x); } }; auto fp = [&](ll a, ll b){ ll r = 1; while(b){ if(b & 1) r = (r * a) % mod; a = (a * a) % mod; b >>= 1; } return r; }; vector <ll> fact(n + 3, 1); for(ll i = 1; i <= n; i ++) fact[i] = (fact[i - 1] * i) % mod; auto c = [&](ll n, ll k){ return (fact[n] * fp((fact[k] * fact[n - k]) % mod, mod - 2)) % mod; }; ll ans = 1; for(int i = 0; i < n; i ++){ int rn = T.find(i); if(is[rn] || T.get(rn) == 1) continue; is[rn] = 1; dfs(wh[rn][0], 0); bool bi = 1; for(auto v: wh[rn]){ for(auto u: g[v]){ if(col[v] == col[u]) bi = 0; } } if(!bi){ ans = (ans * fp(2, T.get(rn) - 1)) % mod; continue; } pii a = mp(0, 0), b = mp(0, 0); for(auto v: wh[rn]){ if(col[v]){ ++ a.st; if(tab[v]) ++ a.nd; } else{ ++ b.st; if(tab[v]) ++ b.nd; } } if(a.nd > b.nd) swap(a, b); ll curr = 0; for(int j = 0; j <= min(a.st, b.st); j ++){ if(j > a.st || j + b.nd - a.nd > b.st) continue; curr = (curr + (c(a.st, j) * c(b.st, j + b.nd - a.nd)) % mod) % mod; } ans = (ans * curr) % mod; } cout << ans << '\n'; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); int t; t = 1; // cin >> t; while(t --) solve(); 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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #include <bits/stdc++.h> #pragma GCC optimize("O3", "unroll-loops") #define pb emplace_back #define ins insert #define mp make_pair #define ssize(x) (int)x.size() #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define pii pair <int, int> #define pll pair <ll, ll> #define pld pair <ld, ld> #define st first #define nd second using namespace std; using ll = int_fast64_t; // using lll = __int128_t; using ld = long double; const int oo = 1e9 + 7; const ll ool = 1e18; const int mod = 1e9 + 7; struct DSU{ vector <int> rep, sz; DSU(int n){ rep.resize(n); sz.assign(n, 1); iota(all(rep), 0); } int find(int x){ if(rep[x] == x) return x; return rep[x] = find(rep[x]); } int get(int x){ return sz[find(x)]; } bool same(int a, int b){ return find(a) == find(b); } void un(int a, int b){ sz[find(a)] += sz[find(b)]; rep[find(b)] = find(a); } }; void solve(){ int n, m; cin >> n >> m; vector <int> tab(n); for(auto &i: tab) cin >> i; vector <vector<int>> g(n); DSU T(n); while(m --){ int a, b; cin >> a >> b; -- a; -- b; g[a].pb(b); g[b].pb(a); if(!T.same(a, b)) T.un(a, b); } vector <vector<int>> wh(n); for(int i = 0; i < n; i ++) wh[T.find(i)].pb(i); vector <bool> is(n), vis(n), col(n); function<void(int, bool)> dfs = [&](int v, bool x){ vis[v] = 1; col[v] = x; for(auto u: g[v]){ if(!vis[u]) dfs(u, !x); } }; auto fp = [&](ll a, ll b){ ll r = 1; while(b){ if(b & 1) r = (r * a) % mod; a = (a * a) % mod; b >>= 1; } return r; }; vector <ll> fact(n + 3, 1); for(ll i = 1; i <= n; i ++) fact[i] = (fact[i - 1] * i) % mod; auto c = [&](ll n, ll k){ return (fact[n] * fp((fact[k] * fact[n - k]) % mod, mod - 2)) % mod; }; ll ans = 1; for(int i = 0; i < n; i ++){ int rn = T.find(i); if(is[rn] || T.get(rn) == 1) continue; is[rn] = 1; dfs(wh[rn][0], 0); bool bi = 1; for(auto v: wh[rn]){ for(auto u: g[v]){ if(col[v] == col[u]) bi = 0; } } if(!bi){ ans = (ans * fp(2, T.get(rn) - 1)) % mod; continue; } pii a = mp(0, 0), b = mp(0, 0); for(auto v: wh[rn]){ if(col[v]){ ++ a.st; if(tab[v]) ++ a.nd; } else{ ++ b.st; if(tab[v]) ++ b.nd; } } if(a.nd > b.nd) swap(a, b); ll curr = 0; for(int j = 0; j <= min(a.st, b.st); j ++){ if(j > a.st || j + b.nd - a.nd > b.st) continue; curr = (curr + (c(a.st, j) * c(b.st, j + b.nd - a.nd)) % mod) % mod; } ans = (ans * curr) % mod; } cout << ans << '\n'; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); int t; t = 1; // cin >> t; while(t --) solve(); return 0; } |