#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; }
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; } |