#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, j) for (int i = 0; i < (int)(j); i++)
const int N = 2e5 + 5;
vector<int> g[N];
int col[N];
int inp_col[N];
int vis[N];
ll siln[N];
ll siln_odw[N];
const ll mod = 1e9 + 7;
ll pow_mod(ll x, ll n) {
if (n == 0)
return 1;
if (n == 1)
return x;
ll hf = pow_mod(x, n / 2);
if (n & 1)
return hf * hf % mod * x % mod;
return hf * hf % mod;
}
tuple<bool, int, int> dfs(int x, int cur_col) {
col[x] = cur_col;
vis[x] = true;
int nie_ok = inp_col[x] != cur_col;
int siz = 1;
bool ok = col;
for (int el : g[x]) {
if (!vis[el]) {
auto [dwu, no, sz] = dfs(el, cur_col ^ 1);
ok &= dwu;
nie_ok += no;
siz += sz;
} else {
ok &= col[el] == (cur_col ^ 1);
}
}
return {ok, nie_ok, siz};
}
void TEST([[maybe_unused]] int testcase_i) {
int n, m;
cin >> n >> m;
rep(i, n) {
cin >> inp_col[i + 1];
}
rep(i, m) {
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
siln[0] = 1;
rep(i, N - 1) {
siln[i + 1] = siln[i] * (i + 1) % mod;
}
siln_odw[N - 1] = pow_mod(siln[N - 1], mod - 2);
for (ll i = N - 2; i >= 0; i--) {
siln_odw[i] = siln_odw[i + 1] * (i + 1) % mod;
}
ll ans = 1;
rep(i, n) {
if (!vis[i + 1]) {
auto [dwu, nie_ok, siz] = dfs(i + 1, 0);
if (!dwu) {
ans = ans * pow_mod(2, siz - 1) % mod;
} else {
ans = ans * siln[siz] % mod * siln_odw[nie_ok] % mod * siln_odw[siz - nie_ok] % mod;
}
}
}
cout << ans;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cout << setprecision(20) << fixed;
// srand(time(NULL));
int t = 1;
// cin >> t;
rep(i, t) {
TEST(i);
}
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 | #include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, j) for (int i = 0; i < (int)(j); i++) const int N = 2e5 + 5; vector<int> g[N]; int col[N]; int inp_col[N]; int vis[N]; ll siln[N]; ll siln_odw[N]; const ll mod = 1e9 + 7; ll pow_mod(ll x, ll n) { if (n == 0) return 1; if (n == 1) return x; ll hf = pow_mod(x, n / 2); if (n & 1) return hf * hf % mod * x % mod; return hf * hf % mod; } tuple<bool, int, int> dfs(int x, int cur_col) { col[x] = cur_col; vis[x] = true; int nie_ok = inp_col[x] != cur_col; int siz = 1; bool ok = col; for (int el : g[x]) { if (!vis[el]) { auto [dwu, no, sz] = dfs(el, cur_col ^ 1); ok &= dwu; nie_ok += no; siz += sz; } else { ok &= col[el] == (cur_col ^ 1); } } return {ok, nie_ok, siz}; } void TEST([[maybe_unused]] int testcase_i) { int n, m; cin >> n >> m; rep(i, n) { cin >> inp_col[i + 1]; } rep(i, m) { int a, b; cin >> a >> b; g[a].push_back(b); g[b].push_back(a); } siln[0] = 1; rep(i, N - 1) { siln[i + 1] = siln[i] * (i + 1) % mod; } siln_odw[N - 1] = pow_mod(siln[N - 1], mod - 2); for (ll i = N - 2; i >= 0; i--) { siln_odw[i] = siln_odw[i + 1] * (i + 1) % mod; } ll ans = 1; rep(i, n) { if (!vis[i + 1]) { auto [dwu, nie_ok, siz] = dfs(i + 1, 0); if (!dwu) { ans = ans * pow_mod(2, siz - 1) % mod; } else { ans = ans * siln[siz] % mod * siln_odw[nie_ok] % mod * siln_odw[siz - nie_ok] % mod; } } } cout << ans; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cout << setprecision(20) << fixed; // srand(time(NULL)); int t = 1; // cin >> t; rep(i, t) { TEST(i); } return 0; } |
English