#define DEBUG
#include <algorithm>
#include <iostream>
#include <unordered_set>
#include <vector>
#ifdef DEBUG
#include <iomanip>
#endif
const long MOD = 1000000007;
const int MAX = 1000005;
// copy from https://cp-algorithms.com/algebra/module-inverse.html
long inv(long a) {
return a <= 1 ? a : MOD - (long)(MOD / a) * inv(MOD % a) % MOD;
}
long F[MAX * 4];
long iF[MAX * 4];
void init() {
F[0] = 1;
for (long i = 1; i < MAX * 4; ++i) F[i] = F[i - 1] * i % MOD;
// for (long i = 1; i < MAX * 4; ++i) iF[i] = inv(F[i]);
}
long C(long k, long n) { return F[n] * inv(F[k]) % MOD * inv(F[n - k]) % MOD; }
long pow(long a, long n) {
long result = 1;
while (n > 0) {
if (n & 1) result = result * a % MOD;
a = a * a % MOD;
n >>= 1;
}
return result;
}
long zeros(long n) {
return C(2 * n - 2, 4 * n - 2) * F[2 * n] % MOD * F[2 * n] % MOD *
inv(pow(4, n)) % MOD;
}
long ones(long n) {
return C(2 * n - 1, 4 * n - 3) * F[2 * n] % MOD * F[2 * n] % MOD *
inv(pow(4, n)) % MOD * 2 % MOD;
}
long solve2(long segments, long ones, long n) {
// std::clog << segments << " / " << ones << std::endl;
long seq = ones * 2 + 2;
long winner = ones;
long tier = ones;
if (ones % 2 == 0) {
if (ones == n)
winner += 1;
else
winner += 2;
} else
tier += 2;
long random_winner = 2 * n - winner;
long random_tier = 2 * n - tier;
// std::clog << "random_winner " << random_winner << " " << random_tier
// << std::endl;
long all = 4 * n;
return ones * ones % MOD * F[random_winner + random_tier] % MOD;
}
int A[MAX * 2];
void solve() {
long n;
std::cin >> n;
bool allzeros = true;
bool allones = true;
bool alltwos = true;
bool anyzero = false;
bool anytwo = false;
int count = 0;
int count_ones = 0;
int parity = -1;
std::unordered_set<int> one_parity;
std::unordered_set<int> zero_parity;
for (int i = 0; i < 2 * n; ++i) {
std::cin >> A[i];
anyzero |= A[i] == 0;
anytwo |= A[i] == 2;
allzeros &= A[i] == 0;
allones &= A[i] == 1;
alltwos &= A[i] == 2;
if (i > 0 && A[i] != A[i - 1]) {
if (A[i - 1] == 1) {
++count_ones;
one_parity.insert((i - 1) % 2);
} else
zero_parity.insert((i - 1) % 2);
++count;
}
}
if (A[2 * n - 1] != A[0]) {
if (A[2 * n - 1] == 1) {
++count_ones;
one_parity.insert((2 * n - 1) % 2);
} else
zero_parity.insert((2 * n - 1) % 2);
++count;
}
bool broken_parity = one_parity.size() > 1 || zero_parity.size() > 1 ||
!one_parity.empty() && !zero_parity.empty() &&
*one_parity.begin() == *zero_parity.begin();
// std::clog << "P: " << one_parity.size() << " " << zero_parity.size()
// << std::endl;
// if (broken_parity) std::clog << "broken_parity" << std::endl;
if (allzeros || alltwos)
std::cout << zeros(n) << std::endl;
else if (allones)
std::cout << ones(n) << std::endl;
else if (anytwo && anyzero || broken_parity)
std::cout << 0 << std::endl;
else
std::cout << solve2(count, count_ones, n) << std::endl;
}
int main() {
std::ios_base::sync_with_stdio(0);
init();
int t;
std::cin >> t;
while (t--) solve();
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 127 128 129 130 131 132 133 134 135 136 | #define DEBUG #include <algorithm> #include <iostream> #include <unordered_set> #include <vector> #ifdef DEBUG #include <iomanip> #endif const long MOD = 1000000007; const int MAX = 1000005; // copy from https://cp-algorithms.com/algebra/module-inverse.html long inv(long a) { return a <= 1 ? a : MOD - (long)(MOD / a) * inv(MOD % a) % MOD; } long F[MAX * 4]; long iF[MAX * 4]; void init() { F[0] = 1; for (long i = 1; i < MAX * 4; ++i) F[i] = F[i - 1] * i % MOD; // for (long i = 1; i < MAX * 4; ++i) iF[i] = inv(F[i]); } long C(long k, long n) { return F[n] * inv(F[k]) % MOD * inv(F[n - k]) % MOD; } long pow(long a, long n) { long result = 1; while (n > 0) { if (n & 1) result = result * a % MOD; a = a * a % MOD; n >>= 1; } return result; } long zeros(long n) { return C(2 * n - 2, 4 * n - 2) * F[2 * n] % MOD * F[2 * n] % MOD * inv(pow(4, n)) % MOD; } long ones(long n) { return C(2 * n - 1, 4 * n - 3) * F[2 * n] % MOD * F[2 * n] % MOD * inv(pow(4, n)) % MOD * 2 % MOD; } long solve2(long segments, long ones, long n) { // std::clog << segments << " / " << ones << std::endl; long seq = ones * 2 + 2; long winner = ones; long tier = ones; if (ones % 2 == 0) { if (ones == n) winner += 1; else winner += 2; } else tier += 2; long random_winner = 2 * n - winner; long random_tier = 2 * n - tier; // std::clog << "random_winner " << random_winner << " " << random_tier // << std::endl; long all = 4 * n; return ones * ones % MOD * F[random_winner + random_tier] % MOD; } int A[MAX * 2]; void solve() { long n; std::cin >> n; bool allzeros = true; bool allones = true; bool alltwos = true; bool anyzero = false; bool anytwo = false; int count = 0; int count_ones = 0; int parity = -1; std::unordered_set<int> one_parity; std::unordered_set<int> zero_parity; for (int i = 0; i < 2 * n; ++i) { std::cin >> A[i]; anyzero |= A[i] == 0; anytwo |= A[i] == 2; allzeros &= A[i] == 0; allones &= A[i] == 1; alltwos &= A[i] == 2; if (i > 0 && A[i] != A[i - 1]) { if (A[i - 1] == 1) { ++count_ones; one_parity.insert((i - 1) % 2); } else zero_parity.insert((i - 1) % 2); ++count; } } if (A[2 * n - 1] != A[0]) { if (A[2 * n - 1] == 1) { ++count_ones; one_parity.insert((2 * n - 1) % 2); } else zero_parity.insert((2 * n - 1) % 2); ++count; } bool broken_parity = one_parity.size() > 1 || zero_parity.size() > 1 || !one_parity.empty() && !zero_parity.empty() && *one_parity.begin() == *zero_parity.begin(); // std::clog << "P: " << one_parity.size() << " " << zero_parity.size() // << std::endl; // if (broken_parity) std::clog << "broken_parity" << std::endl; if (allzeros || alltwos) std::cout << zeros(n) << std::endl; else if (allones) std::cout << ones(n) << std::endl; else if (anytwo && anyzero || broken_parity) std::cout << 0 << std::endl; else std::cout << solve2(count, count_ones, n) << std::endl; } int main() { std::ios_base::sync_with_stdio(0); init(); int t; std::cin >> t; while (t--) solve(); return 0; } |
English