#include <cstdio>
#include <cstdint>
#include <vector>
#include <queue>
using namespace std;
const int64_t MOD = 1000000007;
typedef struct {
vector<int> adj;
bool on;
bool visited;
bool right;
} node_t;
vector<int64_t> P2s;
vector<int64_t> F;
int64_t ext_euclid(int64_t a, int64_t b, int64_t &x, int64_t &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int64_t x1, y1;
int64_t gcd = ext_euclid(b, a % b, x1, y1);
x = y1;
y = x1 - (a / b) * y1;
return gcd;
}
int64_t inverse(int64_t a) {
int64_t x, y;
ext_euclid(a, MOD, x, y);
return x;
}
int64_t BC(int64_t n, int64_t k) {
int64_t ret = (((F[n] * inverse(F[k])) % MOD) * inverse(F[n - k])) % MOD;
return ret >= 0 ? ret : ret + MOD;
}
int main () {
P2s.reserve(200032);
int64_t p2 = 1;
for (int i = 0; i < 200016; ++i) {
P2s.push_back(p2);
p2 = (p2 << 1) % MOD;
}
F.reserve(200032);
int64_t f = 1;
for (int i = 0; i < 200016; ++i) {
F.push_back(f);
f = (f * (i + 1)) % MOD;
}
int n, m;
scanf("%d %d", &n, &m);
node_t node;
node.on = false;
node.visited = false;
node.right = false;
vector<node_t> graph(n, node);
for (int i = 0; i < n; ++i) {
int x;
scanf("%d", &x);
graph[i].on = (x == 1);
}
for (int i = 0; i < m; ++i) {
int x, y;
scanf("%d %d", &x, &y);
--x;
--y;
graph[x].adj.push_back(y);
graph[y].adj.push_back(x);
}
int64_t res = 1;
queue<pair<int, bool> > q;
for (int i = 0; i < n; ++i) {
if (graph[i].visited) {
continue;
}
bool bipartite = true;
int size = 0;
int k = 0;
q.push(make_pair(i, false));
while (!q.empty()) {
pair<int, bool> item = q.front();
int node_i = item.first;
bool is_right = item.second;
q.pop();
if (graph[node_i].visited) {
if (graph[node_i].right != is_right) {
bipartite = false;
}
continue;
}
graph[node_i].visited = true;
graph[node_i].right = is_right;
++size;
if (is_right) {
if (graph[node_i].on) {
++k;
}
}
else {
if (!graph[node_i].on) {
++k;
}
}
for (vector<int>::iterator it = graph[node_i].adj.begin(); it != graph[node_i].adj.end(); it++) {
q.push(make_pair(*it, !is_right));
}
}
if (bipartite) {
res = (res * BC((int64_t)size, (int64_t)k)) % MOD;
}
else {
res = (res * P2s[size - 1]) % MOD;
}
}
printf("%lld\n", res);
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 <cstdio> #include <cstdint> #include <vector> #include <queue> using namespace std; const int64_t MOD = 1000000007; typedef struct { vector<int> adj; bool on; bool visited; bool right; } node_t; vector<int64_t> P2s; vector<int64_t> F; int64_t ext_euclid(int64_t a, int64_t b, int64_t &x, int64_t &y) { if (b == 0) { x = 1; y = 0; return a; } int64_t x1, y1; int64_t gcd = ext_euclid(b, a % b, x1, y1); x = y1; y = x1 - (a / b) * y1; return gcd; } int64_t inverse(int64_t a) { int64_t x, y; ext_euclid(a, MOD, x, y); return x; } int64_t BC(int64_t n, int64_t k) { int64_t ret = (((F[n] * inverse(F[k])) % MOD) * inverse(F[n - k])) % MOD; return ret >= 0 ? ret : ret + MOD; } int main () { P2s.reserve(200032); int64_t p2 = 1; for (int i = 0; i < 200016; ++i) { P2s.push_back(p2); p2 = (p2 << 1) % MOD; } F.reserve(200032); int64_t f = 1; for (int i = 0; i < 200016; ++i) { F.push_back(f); f = (f * (i + 1)) % MOD; } int n, m; scanf("%d %d", &n, &m); node_t node; node.on = false; node.visited = false; node.right = false; vector<node_t> graph(n, node); for (int i = 0; i < n; ++i) { int x; scanf("%d", &x); graph[i].on = (x == 1); } for (int i = 0; i < m; ++i) { int x, y; scanf("%d %d", &x, &y); --x; --y; graph[x].adj.push_back(y); graph[y].adj.push_back(x); } int64_t res = 1; queue<pair<int, bool> > q; for (int i = 0; i < n; ++i) { if (graph[i].visited) { continue; } bool bipartite = true; int size = 0; int k = 0; q.push(make_pair(i, false)); while (!q.empty()) { pair<int, bool> item = q.front(); int node_i = item.first; bool is_right = item.second; q.pop(); if (graph[node_i].visited) { if (graph[node_i].right != is_right) { bipartite = false; } continue; } graph[node_i].visited = true; graph[node_i].right = is_right; ++size; if (is_right) { if (graph[node_i].on) { ++k; } } else { if (!graph[node_i].on) { ++k; } } for (vector<int>::iterator it = graph[node_i].adj.begin(); it != graph[node_i].adj.end(); it++) { q.push(make_pair(*it, !is_right)); } } if (bipartite) { res = (res * BC((int64_t)size, (int64_t)k)) % MOD; } else { res = (res * P2s[size - 1]) % MOD; } } printf("%lld\n", res); return 0; } |
English