//zbugowane, obstawiam 0pkt #include<bits/stdc++.h> using namespace std; typedef long long ll; const ll Q = 1000000007; ll fe(ll a, ll b){ a %= Q; if(b == 0) return 1; if(b < 0) return fe(fe(a, -b), Q - 2); if(b % 2 == 1) return (a * fe(a, b - 1)) % Q; ll c = fe(a, b / 2); return (c * c) % Q; } unordered_map<ll, pair<ll, ll>> SIL; map<pair<ll, ll>, ll> DWSUM; pair<ll, ll> silnia(ll n){ if(n <= 1) return {1, 1}; if(!SIL.count(n)){ silnia(n - 1024);//magiczne przyspieszanie rekurencji ll r = (n * silnia(n - 1).first) % Q; SIL[n] = {r, fe(r, -1)}; } return SIL[n]; } ll dwumian(ll n, ll k){ return (silnia(n).first * ((silnia(k).second * silnia(n - k).second) % Q)) % Q; } ll dwusuma(ll n, ll k){ if(k < 1) return 1; if(!DWSUM.count({n, k})) DWSUM[{n, k}] = (dwusuma(n, k - 1) + dwumian(n, k)) % Q; return DWSUM[{n, k}]; } ll n, a, b, c, d, r[3], res; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; { string s[3]; for(int i = 0;i < 3;i++) cin >> r[i] >> s[i]; for(int i = 0;i < n;i++){ if(s[0][i] == s[1][i] && s[1][i] == s[2][i]){ d++; } else if(s[1][i] == s[2][i]){ a++; } else if(s[0][i] == s[2][i]){ b++; } else if(s[0][i] == s[1][i]){ c++; } else { assert(false); } } } for(ll x = 0;x <= a;x++){ for(ll y = 0;y <= b;y++){ for(ll z = 0;z <= c;z++){ ll px = x + (r[1] - y) + (r[2] - z); ll py = (r[0] - x) + y + (r[2] - z); ll pz = (r[0] - x) + (r[1] - y) + z; ll pw = min(min(min(r[0] - px, r[1] - py), r[2] - pz), d); ll w = (((dwumian(r[0], x) * dwumian(r[1], y)) % Q) * dwumian(r[2], z)) % Q; if(px > r[0] || py > r[1] || pz > r[2]) continue; w = (w * dwusuma(d, pw)) % Q; res += w; } } } cout << res % Q << 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 | //zbugowane, obstawiam 0pkt #include<bits/stdc++.h> using namespace std; typedef long long ll; const ll Q = 1000000007; ll fe(ll a, ll b){ a %= Q; if(b == 0) return 1; if(b < 0) return fe(fe(a, -b), Q - 2); if(b % 2 == 1) return (a * fe(a, b - 1)) % Q; ll c = fe(a, b / 2); return (c * c) % Q; } unordered_map<ll, pair<ll, ll>> SIL; map<pair<ll, ll>, ll> DWSUM; pair<ll, ll> silnia(ll n){ if(n <= 1) return {1, 1}; if(!SIL.count(n)){ silnia(n - 1024);//magiczne przyspieszanie rekurencji ll r = (n * silnia(n - 1).first) % Q; SIL[n] = {r, fe(r, -1)}; } return SIL[n]; } ll dwumian(ll n, ll k){ return (silnia(n).first * ((silnia(k).second * silnia(n - k).second) % Q)) % Q; } ll dwusuma(ll n, ll k){ if(k < 1) return 1; if(!DWSUM.count({n, k})) DWSUM[{n, k}] = (dwusuma(n, k - 1) + dwumian(n, k)) % Q; return DWSUM[{n, k}]; } ll n, a, b, c, d, r[3], res; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; { string s[3]; for(int i = 0;i < 3;i++) cin >> r[i] >> s[i]; for(int i = 0;i < n;i++){ if(s[0][i] == s[1][i] && s[1][i] == s[2][i]){ d++; } else if(s[1][i] == s[2][i]){ a++; } else if(s[0][i] == s[2][i]){ b++; } else if(s[0][i] == s[1][i]){ c++; } else { assert(false); } } } for(ll x = 0;x <= a;x++){ for(ll y = 0;y <= b;y++){ for(ll z = 0;z <= c;z++){ ll px = x + (r[1] - y) + (r[2] - z); ll py = (r[0] - x) + y + (r[2] - z); ll pz = (r[0] - x) + (r[1] - y) + z; ll pw = min(min(min(r[0] - px, r[1] - py), r[2] - pz), d); ll w = (((dwumian(r[0], x) * dwumian(r[1], y)) % Q) * dwumian(r[2], z)) % Q; if(px > r[0] || py > r[1] || pz > r[2]) continue; w = (w * dwusuma(d, pw)) % Q; res += w; } } } cout << res % Q << endl; } |