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