#include <bits/stdc++.h> using namespace std; typedef long long int lli; const int MAXN = 10005; const lli MOD = 1000000007; lli r[3]; char in[MAXN]; lli a[4]; lli npk_tab[MAXN][MAXN]; lli pref[MAXN]; lli mod(lli x) { if (x >= 0) return x%MOD; else return (x%MOD)+MOD; } lli pot(lli x, lli n) { if (n == 0) return 1; if (n%2 == 0) return pot((x*x)%MOD, n/2); else return (x*pot(x, n-1))%MOD; } lli sum(lli low, lli up) { if (low <= 0) return pref[up]; return mod(pref[up]-pref[low-1]); } lli npk(lli n, lli k) { // printf("npk %lld %lld\n", n, k); if (k<0 || k > n) return 0; // printf(" -> %lld\n", npk_tab[n][k]); return npk_tab[n][k]; } void fill_npk(int n) { for (int i=0; i<=n; i++) { for (int j=0; j<=i; j++) { if (j == 0 || j == i) npk_tab[i][j] = 1; else npk_tab[i][j] = (npk_tab[i-1][j-1]+npk_tab[i-1][j])%MOD; } } } int n; vector<int> k[3]; void solve_small() { for (int i=0; i<n; i++) { int id = 2*k[1][i]+k[2][i]; a[id]++; } fill_npk(max(a[0], max(a[1], max(a[2], a[3])))+1); pref[0] = 1; for (int i=1; i<=a[3]; i++) { pref[i] = (pref[i-1]+npk(a[3], i))%MOD; } lli res = 0; for (lli b0=0; b0<=a[0]; b0++) { for (lli b1=0; b1<=a[1]; b1++) { for (lli b2=0; b2<=a[2]; b2++) { // printf("%lld %lld %lld\n", b0, b1, b2); lli c1 = r[0]+1-b0-b1-b2; lli c2 = b0+b1+a[2]-b2+a[3]-r[1]-1; lli c3 = b0+a[1]-b1+b2+a[3]-r[2]-1; // printf("> %lld %lld %lld\n", c1, c2, c3); lli low = c1; lli up = min(c2, min(c3, a[3])); if (up < low) continue; // printf(" %lld %lld\n", low, up); lli tmp = (npk(a[0], b0)*npk(a[1], b1))%MOD; tmp = (tmp*npk(a[2], b2))%MOD; tmp = (tmp*sum(low, up))%MOD; // printf(" %lld\n", tmp); res = mod(res + tmp); } } } printf("%lld", mod(pot(2, n)-res)); } int main() { scanf("%d", &n); for (int i=0; i<3; i++) { scanf("%lld%s", &r[i], in); for (int j=0; j<n; j++) { if (in[j] == '0') k[i].push_back(0); else k[i].push_back(1); } } for (int i=0; i<n; i++) { k[1][i] ^= k[0][i]; k[2][i] ^= k[0][i]; k[0][i] = 0; } solve_small(); 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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #include <bits/stdc++.h> using namespace std; typedef long long int lli; const int MAXN = 10005; const lli MOD = 1000000007; lli r[3]; char in[MAXN]; lli a[4]; lli npk_tab[MAXN][MAXN]; lli pref[MAXN]; lli mod(lli x) { if (x >= 0) return x%MOD; else return (x%MOD)+MOD; } lli pot(lli x, lli n) { if (n == 0) return 1; if (n%2 == 0) return pot((x*x)%MOD, n/2); else return (x*pot(x, n-1))%MOD; } lli sum(lli low, lli up) { if (low <= 0) return pref[up]; return mod(pref[up]-pref[low-1]); } lli npk(lli n, lli k) { // printf("npk %lld %lld\n", n, k); if (k<0 || k > n) return 0; // printf(" -> %lld\n", npk_tab[n][k]); return npk_tab[n][k]; } void fill_npk(int n) { for (int i=0; i<=n; i++) { for (int j=0; j<=i; j++) { if (j == 0 || j == i) npk_tab[i][j] = 1; else npk_tab[i][j] = (npk_tab[i-1][j-1]+npk_tab[i-1][j])%MOD; } } } int n; vector<int> k[3]; void solve_small() { for (int i=0; i<n; i++) { int id = 2*k[1][i]+k[2][i]; a[id]++; } fill_npk(max(a[0], max(a[1], max(a[2], a[3])))+1); pref[0] = 1; for (int i=1; i<=a[3]; i++) { pref[i] = (pref[i-1]+npk(a[3], i))%MOD; } lli res = 0; for (lli b0=0; b0<=a[0]; b0++) { for (lli b1=0; b1<=a[1]; b1++) { for (lli b2=0; b2<=a[2]; b2++) { // printf("%lld %lld %lld\n", b0, b1, b2); lli c1 = r[0]+1-b0-b1-b2; lli c2 = b0+b1+a[2]-b2+a[3]-r[1]-1; lli c3 = b0+a[1]-b1+b2+a[3]-r[2]-1; // printf("> %lld %lld %lld\n", c1, c2, c3); lli low = c1; lli up = min(c2, min(c3, a[3])); if (up < low) continue; // printf(" %lld %lld\n", low, up); lli tmp = (npk(a[0], b0)*npk(a[1], b1))%MOD; tmp = (tmp*npk(a[2], b2))%MOD; tmp = (tmp*sum(low, up))%MOD; // printf(" %lld\n", tmp); res = mod(res + tmp); } } } printf("%lld", mod(pot(2, n)-res)); } int main() { scanf("%d", &n); for (int i=0; i<3; i++) { scanf("%lld%s", &r[i], in); for (int j=0; j<n; j++) { if (in[j] == '0') k[i].push_back(0); else k[i].push_back(1); } } for (int i=0; i<n; i++) { k[1][i] ^= k[0][i]; k[2][i] ^= k[0][i]; k[0][i] = 0; } solve_small(); return 0; } |