#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; } |
English