// Witold Milewski
// PA 2024
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for(int i=a; i<=b; ++i)
#define sz(A) (int)(A.size())
#define eb emplace_back
#define pi pair<int, int>
#define f first
#define s second
#define ll long long
#define pb push_back
const int maxn=2e5+3, maxm=4e5+3, mod=1e9+7;
vector<int> con[maxn];
int stan[maxn];
int spojna[maxn];
int n, m;
bool vis[maxn];
map<string, bool> was;
vector<pi> edges;
vector<pi> kraw[maxn];
vector<int> nodes_in_spojna[maxn];
int which_on_nodes[maxn];
ll wyn[maxn];
int nr;
void dfs(int v) {
vis[v]=1;
spojna[v]=nr;
nodes_in_spojna[nr].eb(v);
which_on_nodes[v]=sz(nodes_in_spojna[nr])-1;
for(int u : con[v]) {
if(vis[u]) continue;
dfs(u);
}
}
void change(int v, string &s) {
if(stan[v]==1) s[which_on_nodes[v]]='0';
else s[which_on_nodes[v]]='1';
stan[v]=1-stan[v];
}
void bt(int spojna, string &stan_grafu) {
if(was[stan_grafu]) return;
was[stan_grafu]=1;
wyn[spojna]=(wyn[spojna]+1)%mod;
for(auto &[a, b] : kraw[spojna]) {
if(stan[a]!=stan[b]) continue;
// zakladamy ze zmieniamy
change(a, stan_grafu);
change(b, stan_grafu);
bt(spojna, stan_grafu);
// zakladamy ze zostawiamy
change(a, stan_grafu);
change(b, stan_grafu);
bt(spojna, stan_grafu);
}
}
int main() {
cin.tie(0) -> ios_base::sync_with_stdio(0);
cin >> n >> m;
FOR(i, 1, n) cin >> stan[i];
int a, b;
FOR(i, 1, m) {
cin >> a >> b;
con[a].eb(b);
con[b].eb(a);
edges.pb({a, b});
}
FOR(i, 1, n) {
++nr;
if(!vis[i]) dfs(i);
}
for(auto &[a, b] : edges) {
kraw[spojna[a]].pb({a, b});
}
FOR(i, 1, nr) {
was.clear();
string stan_grafu = "";
for(int &u : nodes_in_spojna[i]) stan_grafu+=to_string(stan[u]);
bt(i, stan_grafu);
}
// run
ll odp=1;
FOR(i, 1, n) odp=(odp*wyn[i])%mod;
cout << odp << '\n';
}
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 | // Witold Milewski // PA 2024 #include <bits/stdc++.h> using namespace std; #define FOR(i, a, b) for(int i=a; i<=b; ++i) #define sz(A) (int)(A.size()) #define eb emplace_back #define pi pair<int, int> #define f first #define s second #define ll long long #define pb push_back const int maxn=2e5+3, maxm=4e5+3, mod=1e9+7; vector<int> con[maxn]; int stan[maxn]; int spojna[maxn]; int n, m; bool vis[maxn]; map<string, bool> was; vector<pi> edges; vector<pi> kraw[maxn]; vector<int> nodes_in_spojna[maxn]; int which_on_nodes[maxn]; ll wyn[maxn]; int nr; void dfs(int v) { vis[v]=1; spojna[v]=nr; nodes_in_spojna[nr].eb(v); which_on_nodes[v]=sz(nodes_in_spojna[nr])-1; for(int u : con[v]) { if(vis[u]) continue; dfs(u); } } void change(int v, string &s) { if(stan[v]==1) s[which_on_nodes[v]]='0'; else s[which_on_nodes[v]]='1'; stan[v]=1-stan[v]; } void bt(int spojna, string &stan_grafu) { if(was[stan_grafu]) return; was[stan_grafu]=1; wyn[spojna]=(wyn[spojna]+1)%mod; for(auto &[a, b] : kraw[spojna]) { if(stan[a]!=stan[b]) continue; // zakladamy ze zmieniamy change(a, stan_grafu); change(b, stan_grafu); bt(spojna, stan_grafu); // zakladamy ze zostawiamy change(a, stan_grafu); change(b, stan_grafu); bt(spojna, stan_grafu); } } int main() { cin.tie(0) -> ios_base::sync_with_stdio(0); cin >> n >> m; FOR(i, 1, n) cin >> stan[i]; int a, b; FOR(i, 1, m) { cin >> a >> b; con[a].eb(b); con[b].eb(a); edges.pb({a, b}); } FOR(i, 1, n) { ++nr; if(!vis[i]) dfs(i); } for(auto &[a, b] : edges) { kraw[spojna[a]].pb({a, b}); } FOR(i, 1, nr) { was.clear(); string stan_grafu = ""; for(int &u : nodes_in_spojna[i]) stan_grafu+=to_string(stan[u]); bt(i, stan_grafu); } // run ll odp=1; FOR(i, 1, n) odp=(odp*wyn[i])%mod; cout << odp << '\n'; } |
English