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 | #include <iostream>
#include <deque>
#include <array>
#include <vector>
#include <tuple>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <cassert>
using namespace std;
template<typename A, typename B>
ostream& operator<<(ostream& o, const pair<A,B>& d){
o << "(" << d.first << ", " << d.second << ")";
return o;
}
template<typename T>
ostream& operator<<(ostream& o, const vector<T>& d){
o << "[";
for (const T&i:d) o << i << ", ";
o <<"]";
return o;
}
using Kula = pair<int, string>;
Kula rd() {
Kula k; cin>>k.first>>k.second; return k;
}
using LL = long long;
const LL M = ((long long)1e9) + 7;
LL powm(LL a, LL b){
LL r = 1;
while(b){if(b&1) r=r*a%M; a=a*a%M; b/=2;}
return r;
}
vector<LL> fact;
vector<LL> fact_inv;
void setup() {
assert((powm(5,M-2)*5) % M == 1);
fact.push_back(1);fact_inv.push_back(1);
for (int i=1; i <= 1000; i++) {
fact.push_back((fact.back() * i) % M);
fact_inv.push_back(powm(fact.back(), M-2));
}
}
LL choose(LL n, LL k) {
LL z = fact[n];
z *= fact_inv[k];
z %= M;
z *= fact_inv[n-k];
z %= M;
return z;
}
LL solve(Kula A, Kula B, Kula C) {
vector<vector<int>> counts(2, vector<int>(2));
for (int i=0; i < (int)A.second.size(); i++) {
int a = A.second[i]-'0';
int b = B.second[i]-'0';
int c = C.second[i]-'0';
int x = b^a;
int y = c^a;
counts[x][y]++;
}
//cerr << counts << endl;
LL r = 0;
for (int k00=0; k00 <= counts[0][0]; k00 ++) {
for (int k01=0; k01 <= counts[0][1]; k01 ++) {
for (int k10=0; k10 <= counts[1][0]; k10 ++) {
for (int k11=0; k11 <= counts[1][1]; k11 ++) {
int Ac = k00 + k01 + k10 + k11;
int Cc = k00 + (counts[0][1] - k01) + k10 + (counts[1][1] - k11);
int Bc = k00 + k01 + (counts[1][0] - k10) + (counts[1][1] - k11);
//cerr << "O " << k00 << " " << k01 << " " << k10 << " " << k11 << endl;
//cerr << " " << Ac << " " << Bc << " " << Cc << endl;
if (Ac <= A.first || Bc <= B.first || Cc <= C.first) {
LL rr = 1;
rr *= choose(counts[0][0], k00); rr %= M;
rr *= choose(counts[0][1], k01); rr %= M;
rr *= choose(counts[1][0], k10); rr %= M;
rr *= choose(counts[1][1], k11); rr %= M;
//cerr << " Ac " << Ac << " Bc " << Bc << " Cc " << Cc << " rr " << rr << endl;
r += rr;
r %= M;
}
}
}
}
}
return r;
}
int main() {
ios_base::sync_with_stdio(0);
setup();
int n;
cin >> n;
cout << solve(rd(), rd(), rd()) << endl;
}
|