#include<bits/stdc++.h>
#define int long long
using namespace std;
vector<int> Q[210000];
int odw[210000];
int stan[210000];
int t[210000];
int mod=1e9+7;
int nie=0;
int wiel=0;
int ile[2][2];
int mnoz[210000];
int pow(int x,int y)
{
int wynik=1;
while(y>0)
{
if(y%2==1)
{
wynik*=x;
wynik%=mod;
}
x*=x;
x%=mod;
y/=2;
}
return wynik;
}
void reku(int x,int kolor)
{
odw[x]=1;
stan[x]=kolor;
ile[kolor][t[x]]++;
wiel++;
for(int i=0;i<Q[x].size();i++)
{
int pom=Q[x][i];
if(odw[pom]==0)
reku(pom,!kolor);
else{
if(stan[pom]!=(!kolor))
nie=1;
}
}
}
int newton(int x,int y)
{
int wynik=mnoz[x]*pow(mnoz[y],mod-2);
wynik%=mod;
wynik*=pow(mnoz[x-y],mod-2);
wynik%=mod;
return wynik;
}
int32_t main()
{
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio(0);
int n,m,x,y;
cin>>n>>m;
mnoz[0]=1;
for(int i=1;i<=n;i++)
mnoz[i]=mnoz[i-1]*i,mnoz[i]%=mod;
for(int i=1;i<=n;i++)
cin>>t[i];
for(int i=1;i<=m;i++)
{
cin>>x>>y;
Q[x].push_back(y);
Q[y].push_back(x);
}
int wynik=1;
for(int i=1;i<=n;i++)
{
if(odw[i])
continue;
nie=0;
for(int a=0;a<2;a++)
for(int b=0;b<2;b++)
ile[a][b]=0;
wiel=0;
reku(i,0);
if(nie)
{
wynik*=pow(2LL,wiel-1);
wynik%=mod;
}
else{
int essa=0;
int roznica=ile[0][1]-ile[1][1];
int zero=ile[0][0]+ile[0][1];
int jeden=ile[1][0]+ile[1][1];
for(int j=0;j<=jeden;j++)
{
int drugi=j+roznica;
if(drugi<0 || drugi>zero)
continue;
int dodaj=newton(zero,drugi);
dodaj*=newton(jeden,j);
dodaj%=mod;
essa+=dodaj;
essa%=mod;
}
wynik*=essa;
wynik%=mod;
}
}
cout<<wynik;
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 | #include<bits/stdc++.h> #define int long long using namespace std; vector<int> Q[210000]; int odw[210000]; int stan[210000]; int t[210000]; int mod=1e9+7; int nie=0; int wiel=0; int ile[2][2]; int mnoz[210000]; int pow(int x,int y) { int wynik=1; while(y>0) { if(y%2==1) { wynik*=x; wynik%=mod; } x*=x; x%=mod; y/=2; } return wynik; } void reku(int x,int kolor) { odw[x]=1; stan[x]=kolor; ile[kolor][t[x]]++; wiel++; for(int i=0;i<Q[x].size();i++) { int pom=Q[x][i]; if(odw[pom]==0) reku(pom,!kolor); else{ if(stan[pom]!=(!kolor)) nie=1; } } } int newton(int x,int y) { int wynik=mnoz[x]*pow(mnoz[y],mod-2); wynik%=mod; wynik*=pow(mnoz[x-y],mod-2); wynik%=mod; return wynik; } int32_t main() { cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0); int n,m,x,y; cin>>n>>m; mnoz[0]=1; for(int i=1;i<=n;i++) mnoz[i]=mnoz[i-1]*i,mnoz[i]%=mod; for(int i=1;i<=n;i++) cin>>t[i]; for(int i=1;i<=m;i++) { cin>>x>>y; Q[x].push_back(y); Q[y].push_back(x); } int wynik=1; for(int i=1;i<=n;i++) { if(odw[i]) continue; nie=0; for(int a=0;a<2;a++) for(int b=0;b<2;b++) ile[a][b]=0; wiel=0; reku(i,0); if(nie) { wynik*=pow(2LL,wiel-1); wynik%=mod; } else{ int essa=0; int roznica=ile[0][1]-ile[1][1]; int zero=ile[0][0]+ile[0][1]; int jeden=ile[1][0]+ile[1][1]; for(int j=0;j<=jeden;j++) { int drugi=j+roznica; if(drugi<0 || drugi>zero) continue; int dodaj=newton(zero,drugi); dodaj*=newton(jeden,j); dodaj%=mod; essa+=dodaj; essa%=mod; } wynik*=essa; wynik%=mod; } } cout<<wynik; return 0; } |
English