// #pragma GCC optimize("O3") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native") #include <bits/stdc++.h> using namespace std; #define PB emplace_back #define int long long #define ll long long #define vi vector<int> #define siz(a) ((int) ((a).size())) #define rep(i, a, b) for (int i = (a); i <= (b); ++i) #define per(i, a, b) for (int i = (a); i >= (b); --i) void print(vi n) { rep(i, 0, siz(n) - 1) cerr << n[i] << " \n"[i == siz(n) - 1]; } const int N = 4e5, mod = 1e9 + 7; int a, b, s[N + 5], fa[N + 5], p[N + 5][2]; bool vis[N + 5], is[N + 5]; vi st[N + 5]; int fac[N + 5], inv[N + 5]; int qp(int n, int m = mod - 2) { int res = 1; for (; m; m >>= 1) { if (m & 1) res = res * n % mod; n = n * n % mod; } return res; } void init() { fac[0] = fac[1] = 1; rep(i, 2, N) fac[i] = fac[i - 1] * i % mod; inv[N] = qp(fac[N]); per(i, N - 1, 0) inv[i] = inv[i + 1] * (i + 1) % mod; } int C(int n, int m) {return fac[n] * inv[m] % mod * inv[n - m] % mod;} int f(int n) {return fa[n] == n ? n : fa[n] = f(fa[n]);} signed main() { // freopen(".in", "r", stdin); // freopen(".out", "w", stdout); ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); init(); cin >> a >> b; rep(i, 1, a) cin >> s[i], fa[i] = i, fa[i + a] = i + a, p[i][s[i]] = 1; int x, y; rep(i, 1, b) { cin >> x >> y; if(f(x) != f(y + a)) { p[f(y + a)][0] += p[f(x)][0]; p[f(y + a)][1] += p[f(x)][1]; is[f(y + a)] |= is[f(x)]; fa[f(x)] = f(y + a); } if(f(y) != f(x + a)) { p[f(x + a)][0] += p[f(y)][0]; p[f(x + a)][1] += p[f(y)][1]; is[f(x + a)] |= is[f(y)]; fa[f(y)] = f(x + a); } if(s[x] == s[y]) is[f(x)] = is[f(y)] = 1; } int ans = 1; rep(i, 1, a) if(!vis[f(i)]) { vis[f(i)] = vis[f(i + a)] = 1; // cout << i << endl; if(!is[f(i)]) continue; if(f(i) == f(i + a)) { int siz = p[f(i)][0] + p[f(i)][1], tmp = 0; rep(j, 0, siz) if((j & 1) == (p[f(i)][0] & 1)) { // cout << j << endl; (tmp += C(siz, j)) %= mod; } (ans *= tmp) %= mod; } else { int s1 = p[f(i)][0] + p[f(i)][1], s2 = p[f(i + a)][0] + p[f(i + a)][1], tmp = 0; rep(x, 0, s1) { int y = x - p[f(i)][0] + p[f(i + a)][0]; if(y < 0 || y > s2) continue; (tmp += C(s1, x) * C(s2, y)) %= mod; } (ans *= tmp) %= mod; } } cout << ans; return cerr << endl << 1.0 * clock() / CLOCKS_PER_SEC << endl, 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 | // #pragma GCC optimize("O3") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native") #include <bits/stdc++.h> using namespace std; #define PB emplace_back #define int long long #define ll long long #define vi vector<int> #define siz(a) ((int) ((a).size())) #define rep(i, a, b) for (int i = (a); i <= (b); ++i) #define per(i, a, b) for (int i = (a); i >= (b); --i) void print(vi n) { rep(i, 0, siz(n) - 1) cerr << n[i] << " \n"[i == siz(n) - 1]; } const int N = 4e5, mod = 1e9 + 7; int a, b, s[N + 5], fa[N + 5], p[N + 5][2]; bool vis[N + 5], is[N + 5]; vi st[N + 5]; int fac[N + 5], inv[N + 5]; int qp(int n, int m = mod - 2) { int res = 1; for (; m; m >>= 1) { if (m & 1) res = res * n % mod; n = n * n % mod; } return res; } void init() { fac[0] = fac[1] = 1; rep(i, 2, N) fac[i] = fac[i - 1] * i % mod; inv[N] = qp(fac[N]); per(i, N - 1, 0) inv[i] = inv[i + 1] * (i + 1) % mod; } int C(int n, int m) {return fac[n] * inv[m] % mod * inv[n - m] % mod;} int f(int n) {return fa[n] == n ? n : fa[n] = f(fa[n]);} signed main() { // freopen(".in", "r", stdin); // freopen(".out", "w", stdout); ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); init(); cin >> a >> b; rep(i, 1, a) cin >> s[i], fa[i] = i, fa[i + a] = i + a, p[i][s[i]] = 1; int x, y; rep(i, 1, b) { cin >> x >> y; if(f(x) != f(y + a)) { p[f(y + a)][0] += p[f(x)][0]; p[f(y + a)][1] += p[f(x)][1]; is[f(y + a)] |= is[f(x)]; fa[f(x)] = f(y + a); } if(f(y) != f(x + a)) { p[f(x + a)][0] += p[f(y)][0]; p[f(x + a)][1] += p[f(y)][1]; is[f(x + a)] |= is[f(y)]; fa[f(y)] = f(x + a); } if(s[x] == s[y]) is[f(x)] = is[f(y)] = 1; } int ans = 1; rep(i, 1, a) if(!vis[f(i)]) { vis[f(i)] = vis[f(i + a)] = 1; // cout << i << endl; if(!is[f(i)]) continue; if(f(i) == f(i + a)) { int siz = p[f(i)][0] + p[f(i)][1], tmp = 0; rep(j, 0, siz) if((j & 1) == (p[f(i)][0] & 1)) { // cout << j << endl; (tmp += C(siz, j)) %= mod; } (ans *= tmp) %= mod; } else { int s1 = p[f(i)][0] + p[f(i)][1], s2 = p[f(i + a)][0] + p[f(i + a)][1], tmp = 0; rep(x, 0, s1) { int y = x - p[f(i)][0] + p[f(i + a)][0]; if(y < 0 || y > s2) continue; (tmp += C(s1, x) * C(s2, y)) %= mod; } (ans *= tmp) %= mod; } } cout << ans; return cerr << endl << 1.0 * clock() / CLOCKS_PER_SEC << endl, 0; } |