#include <vector> #include <utility> #include <cstdio> #define REP(a, n) for (int a = 0; a < (n); ++a) #define FOR(a, b, c) for (int a = (b); a <= (c); ++a) using namespace std; typedef long long LL; /////////////////////////// #define MOD 1'000'000'007 void gcdExtended(LL a, LL b, LL &x, LL &y) { if (a == 0) { x = 0, y = 1; } else { LL y1; gcdExtended(b % a, a, y, y1); x = y1 - (b / a) * y; } } LL inv(int A) { LL x, y; gcdExtended(A, MOD, x, y); return (x % MOD + MOD) % MOD; } #define MAXN 200005 int byl[MAXN], pocz[MAXN], N; vector<int> sas[MAXN]; int rozm[3], ile1[3], dwudz; void dfs(int a, int s) { if (byl[a] && byl[a]!=s) dwudz = 0; if (byl[a]) return; byl[a] = s; rozm[s]++; ile1[s] += pocz[a]; for (int x : sas[a]) dfs(x, 3-s); } LL res = 1, silnia[MAXN] = {1}; LL noverk(int n, int k) { return silnia[n] * inv(silnia[k]) % MOD * inv(silnia[n-k]) % MOD; } int main() { int M; scanf("%d%d", &N, &M); FOR(a, 1, N) { scanf("%d", &pocz[a]); silnia[a] = silnia[a-1]*a%MOD; } REP(a, M) { int x, y; scanf("%d%d", &x, &y); sas[x].push_back(y); sas[y].push_back(x); } FOR(a, 1, N) if (!byl[a]) { dwudz = 1; ile1[1] = ile1[2] = rozm[1] = rozm[2] = 0; dfs(a, 1); if (dwudz) { LL rr = 0; FOR(i11, 0, rozm[1]) { int i12 = i11-ile1[1]+ile1[2]; if (i12<0 || i12>rozm[2]) continue; rr += noverk(rozm[1], i11) * noverk(rozm[2], i12) % MOD; } // printf("dwudz: %lld\n", rr); res = rr % MOD * res % MOD; } else { int r = rozm[1]+rozm[2]-1; LL w = 1; while (r) { w = w*2 % MOD; --r; } // printf("dowolny: %lld\n", w); res = res * w % MOD; } } printf("%lld\n", res%MOD); }
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 | #include <vector> #include <utility> #include <cstdio> #define REP(a, n) for (int a = 0; a < (n); ++a) #define FOR(a, b, c) for (int a = (b); a <= (c); ++a) using namespace std; typedef long long LL; /////////////////////////// #define MOD 1'000'000'007 void gcdExtended(LL a, LL b, LL &x, LL &y) { if (a == 0) { x = 0, y = 1; } else { LL y1; gcdExtended(b % a, a, y, y1); x = y1 - (b / a) * y; } } LL inv(int A) { LL x, y; gcdExtended(A, MOD, x, y); return (x % MOD + MOD) % MOD; } #define MAXN 200005 int byl[MAXN], pocz[MAXN], N; vector<int> sas[MAXN]; int rozm[3], ile1[3], dwudz; void dfs(int a, int s) { if (byl[a] && byl[a]!=s) dwudz = 0; if (byl[a]) return; byl[a] = s; rozm[s]++; ile1[s] += pocz[a]; for (int x : sas[a]) dfs(x, 3-s); } LL res = 1, silnia[MAXN] = {1}; LL noverk(int n, int k) { return silnia[n] * inv(silnia[k]) % MOD * inv(silnia[n-k]) % MOD; } int main() { int M; scanf("%d%d", &N, &M); FOR(a, 1, N) { scanf("%d", &pocz[a]); silnia[a] = silnia[a-1]*a%MOD; } REP(a, M) { int x, y; scanf("%d%d", &x, &y); sas[x].push_back(y); sas[y].push_back(x); } FOR(a, 1, N) if (!byl[a]) { dwudz = 1; ile1[1] = ile1[2] = rozm[1] = rozm[2] = 0; dfs(a, 1); if (dwudz) { LL rr = 0; FOR(i11, 0, rozm[1]) { int i12 = i11-ile1[1]+ile1[2]; if (i12<0 || i12>rozm[2]) continue; rr += noverk(rozm[1], i11) * noverk(rozm[2], i12) % MOD; } // printf("dwudz: %lld\n", rr); res = rr % MOD * res % MOD; } else { int r = rozm[1]+rozm[2]-1; LL w = 1; while (r) { w = w*2 % MOD; --r; } // printf("dowolny: %lld\n", w); res = res * w % MOD; } } printf("%lld\n", res%MOD); } |