#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair <int, int>; using pll = pair <ll, ll>; using pil = pair <int, ll>; const int inf = 1e9+7; const ll inf_ll = 1e18+7; void boost() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); } struct Spojna { bool cykl_nieparzysty; int parz; int niep; int suma_parz; int suma_niep; }; int n, m, c[200007], a[400007], b[400007], odw[200007]; ll wynik, mod = 1e9+7, silnia[200007], odwr[200007]; vector<int> g[200007]; ll potega(ll base, ll pot) { if (pot == 0) return 1; ll pom = potega(base, pot / 2); pom = (pom * pom) % mod; if (pot % 2 == 0) return pom; return (pom * base) % mod; } ll dwumian(int x, int y) { return (((silnia[x] * odwr[y]) % mod) * odwr[x - y]) % mod; } Spojna dfs(int v, int kol) { odw[v] = kol; int parz = (kol == 1 && c[v] == 1); int niep = (kol == 2 && c[v] == 1); int suma_parz = (kol == 1); int suma_niep = (kol == 2); bool cykl_nieparzysty = false; for (int u: g[v]) { if (odw[u] == 0) { Spojna s = dfs(u, 3 - kol); cykl_nieparzysty |= s.cykl_nieparzysty; parz += s.parz; niep += s.niep; suma_parz += s.suma_parz; suma_niep += s.suma_niep; } else if (odw[u] == kol) { cykl_nieparzysty = true; } } return {cykl_nieparzysty, parz, niep, suma_parz, suma_niep}; } int main() { boost(); cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> c[i]; } for (int i = 1; i <= m; i++) { cin >> a[i] >> b[i]; g[a[i]].push_back(b[i]); g[b[i]].push_back(a[i]); } silnia[0] = 1; for (int i = 1; i <= n; i++) silnia[i] = (silnia[i - 1] * (ll)i) % mod; odwr[n] = potega(silnia[n], mod - 2); for (int i = n - 1; i >= 0; i--) odwr[i] = (odwr[i + 1] * (ll)(i + 1)) % mod; wynik = 1; for (int i = 1; i <= n; i++) { if (odw[i] == 0) { for (int u: g[i]) { if (c[i] == c[u]) { Spojna s = dfs(i, 1); int parz = s.parz; int niep = s.niep; int suma_parz = s.suma_parz; int suma_niep = s.suma_niep; //cout << i << ": " << parz << " " << niep << " " << suma_parz << " " << suma_niep << " " << s.cykl_nieparzysty << "\n"; ll pom = 0; if (s.cykl_nieparzysty == true) { for (int i = ((parz + niep) % 2); i <= (suma_parz + suma_niep); i += 2) { pom += dwumian(suma_parz + suma_niep, i); pom %= mod; //cout << "pom: " << pom << "\n"; } } else { while (parz > 0 && niep > 0) { parz--; niep--; } while (parz <= suma_parz && niep <= suma_niep) { pom += dwumian(suma_parz, parz) * dwumian(suma_niep, niep); pom %= mod; //cout << "pom: " << pom << "\n"; parz++; niep++; } } wynik = (wynik * pom) % mod; break; } } } } cout << wynik << "\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 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 127 128 129 | #include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair <int, int>; using pll = pair <ll, ll>; using pil = pair <int, ll>; const int inf = 1e9+7; const ll inf_ll = 1e18+7; void boost() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); } struct Spojna { bool cykl_nieparzysty; int parz; int niep; int suma_parz; int suma_niep; }; int n, m, c[200007], a[400007], b[400007], odw[200007]; ll wynik, mod = 1e9+7, silnia[200007], odwr[200007]; vector<int> g[200007]; ll potega(ll base, ll pot) { if (pot == 0) return 1; ll pom = potega(base, pot / 2); pom = (pom * pom) % mod; if (pot % 2 == 0) return pom; return (pom * base) % mod; } ll dwumian(int x, int y) { return (((silnia[x] * odwr[y]) % mod) * odwr[x - y]) % mod; } Spojna dfs(int v, int kol) { odw[v] = kol; int parz = (kol == 1 && c[v] == 1); int niep = (kol == 2 && c[v] == 1); int suma_parz = (kol == 1); int suma_niep = (kol == 2); bool cykl_nieparzysty = false; for (int u: g[v]) { if (odw[u] == 0) { Spojna s = dfs(u, 3 - kol); cykl_nieparzysty |= s.cykl_nieparzysty; parz += s.parz; niep += s.niep; suma_parz += s.suma_parz; suma_niep += s.suma_niep; } else if (odw[u] == kol) { cykl_nieparzysty = true; } } return {cykl_nieparzysty, parz, niep, suma_parz, suma_niep}; } int main() { boost(); cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> c[i]; } for (int i = 1; i <= m; i++) { cin >> a[i] >> b[i]; g[a[i]].push_back(b[i]); g[b[i]].push_back(a[i]); } silnia[0] = 1; for (int i = 1; i <= n; i++) silnia[i] = (silnia[i - 1] * (ll)i) % mod; odwr[n] = potega(silnia[n], mod - 2); for (int i = n - 1; i >= 0; i--) odwr[i] = (odwr[i + 1] * (ll)(i + 1)) % mod; wynik = 1; for (int i = 1; i <= n; i++) { if (odw[i] == 0) { for (int u: g[i]) { if (c[i] == c[u]) { Spojna s = dfs(i, 1); int parz = s.parz; int niep = s.niep; int suma_parz = s.suma_parz; int suma_niep = s.suma_niep; //cout << i << ": " << parz << " " << niep << " " << suma_parz << " " << suma_niep << " " << s.cykl_nieparzysty << "\n"; ll pom = 0; if (s.cykl_nieparzysty == true) { for (int i = ((parz + niep) % 2); i <= (suma_parz + suma_niep); i += 2) { pom += dwumian(suma_parz + suma_niep, i); pom %= mod; //cout << "pom: " << pom << "\n"; } } else { while (parz > 0 && niep > 0) { parz--; niep--; } while (parz <= suma_parz && niep <= suma_niep) { pom += dwumian(suma_parz, parz) * dwumian(suma_niep, niep); pom %= mod; //cout << "pom: " << pom << "\n"; parz++; niep++; } } wynik = (wynik * pom) % mod; break; } } } } cout << wynik << "\n"; return 0; } |