// 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'; } |