#include <algorithm> #include <cstdio> using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define INT(x) int x; scanf("%d", &x) typedef long long LL; const int mod = 1000000007; int n; int r[3]; char s[3][10001]; int same; int diff[3]; LL fac[10001]; LL rfac[10001]; LL EXTEUC(LL a, LL b, LL& x, LL& y) { x = 1; y = 0; LL x1 = 0, y1 = 1; while (b != 0) { LL t = b; LL q = a / b; b = a % b; a = t; t = x1; x1 = x - q * x1; x = t; t = y1; y1 = y - q * y1; y = t; } return a; } inline LL MODL(LL a, LL b) { return a >= 0 ? a % b : b + ((a + 1) % b) - 1; } LL REVM(LL a, LL m) { LL x, y; EXTEUC(m, a, x, y); return MODL(y, m); } LL binom(LL n, LL k) { return fac[n] * rfac[k] % mod * rfac[n - k] % mod; } LL sumBinom(LL n, LL k) { int res = 0; REP(i,k+1) res = (res + binom(n, i)) % mod; return res; } int vol(int a) { return sumBinom(n, r[a]); } int inter2(int a, int b) { int same2 = 0; int diff2 = 0; REP(i,n) if (s[a][i] == s[b][i]) ++same2; else ++diff2; int res = 0; int dmi = diff2 - r[a], dma = r[b] + 1; FOR(d0,dmi,dma) { LL f = binom(diff2, d0); int r0 = r[a] - diff2 + d0, r1 = r[b] - d0; int sma = min(min(r0, r1), same2); res = (res + (f * sumBinom(same2, sma) % mod)) % mod; } return res; } int inter3() { int res = 0; int d0mi = diff[0] - r[0], d0ma = min(r[1], r[2]) + 1; FOR(d0,d0mi,d0ma) { LL f0 = binom(diff[0], d0); int r0 = r[0] - diff[0] + d0, r1 = r[1] - d0, r2 = r[2] - d0; int d1mi = diff[1] - r1, d1ma = min(r0, r2) + 1; FOR(d1,d1mi,d1ma) { LL f1 = (f0 * binom(diff[1], d1)) % mod; int rr0 = r0 - d1, rr1 = r1 - diff[1] + d1, rr2 = r2 - d1; int d2mi = diff[2] - rr2, d2ma = min(rr0, rr1) + 1; FOR(d2,d2mi,d2ma) { LL f2 = (f1 * binom(diff[2], d2)) % mod; int rrr0 = rr0 - d2, rrr1 = rr1 - d2, rrr2 = rr2 - diff[2] + d2; int sma = min(min(min(rrr0, rrr1), rrr2), same); res = (res + (f2 * sumBinom(same, sma) % mod)) % mod; } } } return res; } int main() { INT(n1); n = n1; fac[0] = 1; FOR(i,1,n+1) fac[i] = fac[i - 1] * i % mod; REP(i,n+1) rfac[i] = REVM(fac[i], mod); REP(k,3) scanf("%d%s", &r[k], &s[k]); REP(i,n) if (s[0][i] == s[1][i] && s[1][i] == s[2][i]) ++same; else REP(k,3) if (s[(k + 1) % 3][i] == s[(k + 2) % 3][i]) ++diff[k]; printf("%d\n", vol(0) + vol(1) + vol(2) - inter2(0, 1) - inter2(0, 2) - inter2(1, 2) + inter3()); }
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 111 112 113 | #include <algorithm> #include <cstdio> using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define INT(x) int x; scanf("%d", &x) typedef long long LL; const int mod = 1000000007; int n; int r[3]; char s[3][10001]; int same; int diff[3]; LL fac[10001]; LL rfac[10001]; LL EXTEUC(LL a, LL b, LL& x, LL& y) { x = 1; y = 0; LL x1 = 0, y1 = 1; while (b != 0) { LL t = b; LL q = a / b; b = a % b; a = t; t = x1; x1 = x - q * x1; x = t; t = y1; y1 = y - q * y1; y = t; } return a; } inline LL MODL(LL a, LL b) { return a >= 0 ? a % b : b + ((a + 1) % b) - 1; } LL REVM(LL a, LL m) { LL x, y; EXTEUC(m, a, x, y); return MODL(y, m); } LL binom(LL n, LL k) { return fac[n] * rfac[k] % mod * rfac[n - k] % mod; } LL sumBinom(LL n, LL k) { int res = 0; REP(i,k+1) res = (res + binom(n, i)) % mod; return res; } int vol(int a) { return sumBinom(n, r[a]); } int inter2(int a, int b) { int same2 = 0; int diff2 = 0; REP(i,n) if (s[a][i] == s[b][i]) ++same2; else ++diff2; int res = 0; int dmi = diff2 - r[a], dma = r[b] + 1; FOR(d0,dmi,dma) { LL f = binom(diff2, d0); int r0 = r[a] - diff2 + d0, r1 = r[b] - d0; int sma = min(min(r0, r1), same2); res = (res + (f * sumBinom(same2, sma) % mod)) % mod; } return res; } int inter3() { int res = 0; int d0mi = diff[0] - r[0], d0ma = min(r[1], r[2]) + 1; FOR(d0,d0mi,d0ma) { LL f0 = binom(diff[0], d0); int r0 = r[0] - diff[0] + d0, r1 = r[1] - d0, r2 = r[2] - d0; int d1mi = diff[1] - r1, d1ma = min(r0, r2) + 1; FOR(d1,d1mi,d1ma) { LL f1 = (f0 * binom(diff[1], d1)) % mod; int rr0 = r0 - d1, rr1 = r1 - diff[1] + d1, rr2 = r2 - d1; int d2mi = diff[2] - rr2, d2ma = min(rr0, rr1) + 1; FOR(d2,d2mi,d2ma) { LL f2 = (f1 * binom(diff[2], d2)) % mod; int rrr0 = rr0 - d2, rrr1 = rr1 - d2, rrr2 = rr2 - diff[2] + d2; int sma = min(min(min(rrr0, rrr1), rrr2), same); res = (res + (f2 * sumBinom(same, sma) % mod)) % mod; } } } return res; } int main() { INT(n1); n = n1; fac[0] = 1; FOR(i,1,n+1) fac[i] = fac[i - 1] * i % mod; REP(i,n+1) rfac[i] = REVM(fac[i], mod); REP(k,3) scanf("%d%s", &r[k], &s[k]); REP(i,n) if (s[0][i] == s[1][i] && s[1][i] == s[2][i]) ++same; else REP(k,3) if (s[(k + 1) % 3][i] == s[(k + 2) % 3][i]) ++diff[k]; printf("%d\n", vol(0) + vol(1) + vol(2) - inter2(0, 1) - inter2(0, 2) - inter2(1, 2) + inter3()); } |