#include <bits/stdc++.h> using namespace std; constexpr int M = 200'005; constexpr long long MOD = 1e9+7; vector<vector<long long>> g(M); long long stan[M]; long long spojna[M]; pair<pair<long long, long long>, pair<long long, long long>> rozmiary[M]; long long dwudziel[M]; //0 jeszcze nie, 1 da sie, 2 nie da sie long long kolory[M]; long long silnia[M]; bool odw[M]; long long wielkosc[M]; void dfs(long long v, long long kolor){ spojna[v] = kolor; wielkosc[kolor]++; for(auto i:g[v]) if(!spojna[i]) dfs(i, kolor); } bool czySieDa = 1; void dfsk(long long v, long long kolor){ kolory[v] = kolor; for(auto i:g[v]){ if(kolory[i]==0){ if(kolory[v]==1) dfsk(i, 2); else dfsk(i, 1); } else if(kolory[i]==1 && kolory[v]==1) czySieDa = 0; else if(kolory[i]==2 && kolory[v]==2) czySieDa = 0; } } void dfskk(long long v){ odw[v] = 1; if(stan[v]==1 && kolory[v]==1) rozmiary[spojna[v]].first.first++; else if(stan[v]==1 && kolory[v]==2) rozmiary[spojna[v]].first.second++; else if(stan[v]==0 && kolory[v]==1) rozmiary[spojna[v]].second.first++; else if(stan[v]==0 && kolory[v]==2) rozmiary[spojna[v]].second.second++; for(auto i:g[v]) if(!odw[i]) dfskk(i); } long long pote(long long a, long long b){ long long w = 1; while(b>0){ if (b%2 == 1) w = (a*w)%MOD; a = (a*a)%MOD; b/=2; } return w%MOD; } long long odwrotnosc(long long a){ return pote(a, MOD-2); } long long apob(long long a, long long b){ long long temp = 0; return (((silnia[a]*odwrotnosc(silnia[b]))%MOD)*odwrotnosc(silnia[max(a-b, temp)]))%MOD; } int main() { cin.tie(0)->sync_with_stdio(0); long long n, m; cin>>n>>m; silnia[0] = 1; for(int i=1; i<=n; i++) silnia[i] = (silnia[i-1]*i)%MOD; for(int i=1; i<=n; i++) cin>>stan[i]; for(int i=1; i<=m; i++){ int a, b; cin>>a>>b; g[a].push_back(b); g[b].push_back(a); } long long ileS = 0; for(int i=1; i<=n; i++) if(!spojna[i]) dfs(i, ++ileS); for(int i=1; i<=n; i++) if(!kolory[i]){ czySieDa = 1; dfsk(i, 1); if(czySieDa==1){ dfskk(i); dwudziel[spojna[i]] = 2; } else dwudziel[spojna[i]] = 1; } long long wynik = 1; long long tempWyn; for(int i=1; i<=ileS; i++){ if(dwudziel[i]==1 || dwudziel[i]==0) wynik = (wynik*pote(2, wielkosc[i]-1))% MOD; else{ tempWyn=0; long long a=rozmiary[i].second.first, b=rozmiary[i].second.second, c=rozmiary[i].first.first, d=rozmiary[i].first.second; while(b<=rozmiary[i].second.first+rozmiary[i].second.second && d<=rozmiary[i].first.first+rozmiary[i].first.second && a>=0 && c>=0){ tempWyn = (tempWyn + (apob(a+b, a)*apob(c+d, c))) % MOD; b++, d++, a--, c--; } a=rozmiary[i].second.first+1, b=rozmiary[i].second.second-1, c=rozmiary[i].first.first+1, d=rozmiary[i].first.second-1; while(d>=0 && b>=0){ tempWyn = (tempWyn + (apob(a+b, a)*apob(c+d, c))) % MOD; a++, c++, b--, d--; } wynik = (wynik*tempWyn)%MOD; } } cout<<wynik%MOD<<endl; 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 | #include <bits/stdc++.h> using namespace std; constexpr int M = 200'005; constexpr long long MOD = 1e9+7; vector<vector<long long>> g(M); long long stan[M]; long long spojna[M]; pair<pair<long long, long long>, pair<long long, long long>> rozmiary[M]; long long dwudziel[M]; //0 jeszcze nie, 1 da sie, 2 nie da sie long long kolory[M]; long long silnia[M]; bool odw[M]; long long wielkosc[M]; void dfs(long long v, long long kolor){ spojna[v] = kolor; wielkosc[kolor]++; for(auto i:g[v]) if(!spojna[i]) dfs(i, kolor); } bool czySieDa = 1; void dfsk(long long v, long long kolor){ kolory[v] = kolor; for(auto i:g[v]){ if(kolory[i]==0){ if(kolory[v]==1) dfsk(i, 2); else dfsk(i, 1); } else if(kolory[i]==1 && kolory[v]==1) czySieDa = 0; else if(kolory[i]==2 && kolory[v]==2) czySieDa = 0; } } void dfskk(long long v){ odw[v] = 1; if(stan[v]==1 && kolory[v]==1) rozmiary[spojna[v]].first.first++; else if(stan[v]==1 && kolory[v]==2) rozmiary[spojna[v]].first.second++; else if(stan[v]==0 && kolory[v]==1) rozmiary[spojna[v]].second.first++; else if(stan[v]==0 && kolory[v]==2) rozmiary[spojna[v]].second.second++; for(auto i:g[v]) if(!odw[i]) dfskk(i); } long long pote(long long a, long long b){ long long w = 1; while(b>0){ if (b%2 == 1) w = (a*w)%MOD; a = (a*a)%MOD; b/=2; } return w%MOD; } long long odwrotnosc(long long a){ return pote(a, MOD-2); } long long apob(long long a, long long b){ long long temp = 0; return (((silnia[a]*odwrotnosc(silnia[b]))%MOD)*odwrotnosc(silnia[max(a-b, temp)]))%MOD; } int main() { cin.tie(0)->sync_with_stdio(0); long long n, m; cin>>n>>m; silnia[0] = 1; for(int i=1; i<=n; i++) silnia[i] = (silnia[i-1]*i)%MOD; for(int i=1; i<=n; i++) cin>>stan[i]; for(int i=1; i<=m; i++){ int a, b; cin>>a>>b; g[a].push_back(b); g[b].push_back(a); } long long ileS = 0; for(int i=1; i<=n; i++) if(!spojna[i]) dfs(i, ++ileS); for(int i=1; i<=n; i++) if(!kolory[i]){ czySieDa = 1; dfsk(i, 1); if(czySieDa==1){ dfskk(i); dwudziel[spojna[i]] = 2; } else dwudziel[spojna[i]] = 1; } long long wynik = 1; long long tempWyn; for(int i=1; i<=ileS; i++){ if(dwudziel[i]==1 || dwudziel[i]==0) wynik = (wynik*pote(2, wielkosc[i]-1))% MOD; else{ tempWyn=0; long long a=rozmiary[i].second.first, b=rozmiary[i].second.second, c=rozmiary[i].first.first, d=rozmiary[i].first.second; while(b<=rozmiary[i].second.first+rozmiary[i].second.second && d<=rozmiary[i].first.first+rozmiary[i].first.second && a>=0 && c>=0){ tempWyn = (tempWyn + (apob(a+b, a)*apob(c+d, c))) % MOD; b++, d++, a--, c--; } a=rozmiary[i].second.first+1, b=rozmiary[i].second.second-1, c=rozmiary[i].first.first+1, d=rozmiary[i].first.second-1; while(d>=0 && b>=0){ tempWyn = (tempWyn + (apob(a+b, a)*apob(c+d, c))) % MOD; a++, c++, b--, d--; } wynik = (wynik*tempWyn)%MOD; } } cout<<wynik%MOD<<endl; return 0; } |