#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll MOD = (ll)1e9 + 7LL;
ll silnia(ll n)
{
if (n == 0)
return 1;
return n * silnia(n - 1);
}
ll powerr(ll a, ll b)
{
if (b == 0)
return 1;
return a * powerr(a, b - 1);
}
int main()
{
// ios_base::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
int z;
cin >> z;
while (z--)
{
ll n;
cin >> n;
vector<ll> ciag(2 * n);
bool hasTwo = false;
bool hasZ = false;
for (int i = 0; i < 2 * n; i++)
{
cin >> ciag[i];
if (ciag[i] == 2)
hasTwo = true;
if (ciag[i] == 0)
hasZ = true;
}
if (hasTwo && hasZ)
{
cout << "0\n";
continue;
}
if (hasTwo)
{
rotate(ciag.begin(), ciag.begin() + 1, ciag.end());
for (int i = 0; i < 2 * n; i++)
{
ciag[i] = ciag[i] % 2;
}
}
bool onlyZ = true;
bool onlyOne = true;
for (int i = 0; i < 2 * n; i++)
{
if (ciag[i] == 1)
{
onlyZ = false;
}
else
{
onlyOne = false;
}
}
if (onlyOne)
{
// cout << 2 * (ll)n * (ll)n * (ll)(n - 1) * silnia(4 * n - 3) / powerr(2, 2 * n - 3) +
// (ll)n * (ll)n * silnia(4 * n - 3) / powerr(2, 2 * n - 2)
// << "\n";
cout << 2 * 2 * n * 2 * n * (2 * n - 1) * silnia(4 * n - 3) / powerr(2, 2 * n) << "\n";
continue;
}
if (onlyZ)
{
cout << (ll)n * (ll)(n - 1) * silnia(4 * n - 2) / powerr(2, 2 * n - 2) +
(ll)n * silnia(4 * n - 2) / powerr(2, 2 * n - 1)
<< "\n";
continue;
}
bool blad = false;
ciag.push_back(ciag.front());
deque<ll> przeskoki01, przeskoki10, przeskoki01R;
for (int i = 0; i + 1 < ciag.size(); i++)
{
if (ciag[i] != ciag[i + 1])
{
if (ciag[i] == 1)
{
if ((i % 2))
{
blad = true;
break;
}
przeskoki10.push_back(i);
}
else
{
if (!(i % 2))
{
blad = true;
break;
}
przeskoki01.push_back(i);
przeskoki01R.push_back(i);
}
}
}
if (blad)
{
cout << "0\n";
continue;
}
if (przeskoki01.front() < przeskoki10.front())
{
przeskoki01.push_back(przeskoki01.front() + ciag.size() - 1);
przeskoki01.pop_front();
}
if (przeskoki01R.front() > przeskoki10.front())
{
przeskoki01R.push_front(przeskoki01R.back() - ciag.size() + 1);
przeskoki01R.pop_back();
}
ll wyn = 0;
// for (auto x : przeskoki01)
// {
// cout << x << " ";
// }
// cout << "\n";
// for (auto x : przeskoki10)
// {
// cout << x << " ";
// }
// cout << "\n";
// for (auto x : przeskoki01R)
// {
// cout << x << " ";
// }
// cout << "\n";
for (int i = 0; i < przeskoki10.size(); i++)
{
ll pom = (przeskoki01[i] - przeskoki10[i]) / 2;
pom *= 2;
// cout << "pom" << pom << "\n";
ll pom2 = 2 * n - pom - przeskoki10.size();
ll pom3 = (przeskoki10[i] - przeskoki01R[i]) / 2;
pom3 *= 2;
ll pom4 = 2 * n - pom3 - przeskoki01.size();
// cout << pom3 << "\n";
// cout << "pom2" << pom2 << "\n";
// cout << pom * (2 * n - przeskoki10.size() - 1) * silnia(4 * n - 2 - przeskoki01.size() - przeskoki10.size()) * powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()) << "\n";
// cout << pom2 * silnia(4 * n - 1 - przeskoki01.size() - przeskoki10.size()) * powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()) << "\n";
// cout << 2 * (pom3 - 1) * silnia(4 * n - przeskoki01.size() - przeskoki10.size() - 2) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()) << "\n";
wyn += pom * (2 * n - przeskoki10.size() - 1) * silnia(4 * n - 2 - przeskoki01.size() - przeskoki10.size()) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size());
wyn += pom2 * silnia(4 * n - 1 - przeskoki01.size() - przeskoki10.size()) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size());
wyn += (pom3) * (pom4)*silnia(4 * n - przeskoki01.size() - przeskoki10.size() - 2) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size());
if (pom3)
wyn += (pom3) * (pom3) * (2 * n - przeskoki10.size() - 1) * silnia(4 * n - przeskoki01.size() - przeskoki10.size() - 3) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size());
}
cout << wyn % MOD << "\n";
}
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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | #include <bits/stdc++.h> using namespace std; using ll = long long; constexpr ll MOD = (ll)1e9 + 7LL; ll silnia(ll n) { if (n == 0) return 1; return n * silnia(n - 1); } ll powerr(ll a, ll b) { if (b == 0) return 1; return a * powerr(a, b - 1); } int main() { // ios_base::sync_with_stdio(0); // cin.tie(0); // cout.tie(0); int z; cin >> z; while (z--) { ll n; cin >> n; vector<ll> ciag(2 * n); bool hasTwo = false; bool hasZ = false; for (int i = 0; i < 2 * n; i++) { cin >> ciag[i]; if (ciag[i] == 2) hasTwo = true; if (ciag[i] == 0) hasZ = true; } if (hasTwo && hasZ) { cout << "0\n"; continue; } if (hasTwo) { rotate(ciag.begin(), ciag.begin() + 1, ciag.end()); for (int i = 0; i < 2 * n; i++) { ciag[i] = ciag[i] % 2; } } bool onlyZ = true; bool onlyOne = true; for (int i = 0; i < 2 * n; i++) { if (ciag[i] == 1) { onlyZ = false; } else { onlyOne = false; } } if (onlyOne) { // cout << 2 * (ll)n * (ll)n * (ll)(n - 1) * silnia(4 * n - 3) / powerr(2, 2 * n - 3) + // (ll)n * (ll)n * silnia(4 * n - 3) / powerr(2, 2 * n - 2) // << "\n"; cout << 2 * 2 * n * 2 * n * (2 * n - 1) * silnia(4 * n - 3) / powerr(2, 2 * n) << "\n"; continue; } if (onlyZ) { cout << (ll)n * (ll)(n - 1) * silnia(4 * n - 2) / powerr(2, 2 * n - 2) + (ll)n * silnia(4 * n - 2) / powerr(2, 2 * n - 1) << "\n"; continue; } bool blad = false; ciag.push_back(ciag.front()); deque<ll> przeskoki01, przeskoki10, przeskoki01R; for (int i = 0; i + 1 < ciag.size(); i++) { if (ciag[i] != ciag[i + 1]) { if (ciag[i] == 1) { if ((i % 2)) { blad = true; break; } przeskoki10.push_back(i); } else { if (!(i % 2)) { blad = true; break; } przeskoki01.push_back(i); przeskoki01R.push_back(i); } } } if (blad) { cout << "0\n"; continue; } if (przeskoki01.front() < przeskoki10.front()) { przeskoki01.push_back(przeskoki01.front() + ciag.size() - 1); przeskoki01.pop_front(); } if (przeskoki01R.front() > przeskoki10.front()) { przeskoki01R.push_front(przeskoki01R.back() - ciag.size() + 1); przeskoki01R.pop_back(); } ll wyn = 0; // for (auto x : przeskoki01) // { // cout << x << " "; // } // cout << "\n"; // for (auto x : przeskoki10) // { // cout << x << " "; // } // cout << "\n"; // for (auto x : przeskoki01R) // { // cout << x << " "; // } // cout << "\n"; for (int i = 0; i < przeskoki10.size(); i++) { ll pom = (przeskoki01[i] - przeskoki10[i]) / 2; pom *= 2; // cout << "pom" << pom << "\n"; ll pom2 = 2 * n - pom - przeskoki10.size(); ll pom3 = (przeskoki10[i] - przeskoki01R[i]) / 2; pom3 *= 2; ll pom4 = 2 * n - pom3 - przeskoki01.size(); // cout << pom3 << "\n"; // cout << "pom2" << pom2 << "\n"; // cout << pom * (2 * n - przeskoki10.size() - 1) * silnia(4 * n - 2 - przeskoki01.size() - przeskoki10.size()) * powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()) << "\n"; // cout << pom2 * silnia(4 * n - 1 - przeskoki01.size() - przeskoki10.size()) * powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()) << "\n"; // cout << 2 * (pom3 - 1) * silnia(4 * n - przeskoki01.size() - przeskoki10.size() - 2) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()) << "\n"; wyn += pom * (2 * n - przeskoki10.size() - 1) * silnia(4 * n - 2 - przeskoki01.size() - przeskoki10.size()) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()); wyn += pom2 * silnia(4 * n - 1 - przeskoki01.size() - przeskoki10.size()) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()); wyn += (pom3) * (pom4)*silnia(4 * n - przeskoki01.size() - przeskoki10.size() - 2) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()); if (pom3) wyn += (pom3) * (pom3) * (2 * n - przeskoki10.size() - 1) * silnia(4 * n - przeskoki01.size() - przeskoki10.size() - 3) / powerr(2, 2 * n - przeskoki01.size() - przeskoki10.size()); } cout << wyn % MOD << "\n"; } return 0; } |
English