#include <cstdio>
// *** MODULAR INVERSE CODE FROM https://tfetimes.com/c-modular-inverse/ ***
int mul_inv(int a, int b)
{
int b0 = b, t, q;
int x0 = 0, x1 = 1;
if (b == 1) return 1;
while (a > 1) {
q = a / b;
t = b, b = a % b, a = t;
t = x0, x0 = x1 - q * x0, x1 = t;
}
if (x1 < 0) x1 += b0;
return x1;
}
const unsigned MOD = 1000000007u;
const unsigned long MODL = 1000000007lu;
class Mod
{
unsigned value;
public:
Mod(int x = 0) : value(x % MOD) { }
Mod(unsigned x) : value(x % MOD) { }
Mod(unsigned long x) : value(x % MODL) { }
Mod operator*(const int x) const {
return Mod(static_cast<unsigned long>(value) * static_cast<unsigned long>(x));
}
Mod operator*(Mod x) const {
return Mod(static_cast<unsigned long>(value) * static_cast<unsigned long>(x.value));
}
Mod operator+(Mod x) const {
return Mod(static_cast<unsigned long>(value) + static_cast<unsigned long>(x.value));
}
Mod operator-(Mod x) const {
return Mod(static_cast<unsigned long>(value) + static_cast<unsigned long>(MOD - x.value));
}
Mod operator/(Mod x) const {
return Mod(static_cast<unsigned long>(value) * static_cast<unsigned long>(mul_inv(x.value, MOD)));
}
unsigned get() const {
return value;
}
Mod inv() const {
return mul_inv(value, MOD);
}
};
Mod F[4000001]; // n!
Mod D[4000001]; // 2^n
Mod invD[4000001]; // 1/2^n
Mod policz111(int N)
{
// 1 1 1 ... 1
// karta 2N w jednej drużynie, a 2N-1 w drugiej
//return mul_inv(D[N-2].get(), MOD);
//return Mod(N) * (N/2) * (N*2-3) * F[N*2-4] * invD[N-2];
return Mod(N) * (N/2) * (N*2-3) * F[N*2-4] * invD[N-2] + Mod(N) * (N/2) * (N/2-1) * (N*2-3) * (N*2-4) * (N*2-5) * F[N*2-6] * invD[N-3];
}
int X[1000000];
// N u mnie znaczy liczbę graczy
Mod dawaj(int N)
{
int ile[3] = {0, 0, 0};
int ileA[3] = {0, 0, 0};
int ileP[3] = {0, 0, 0};
for (int i=0; i<N; ++i) {
ile[X[i]]++;
}
for (int i=0; i<N; i+=2) {
ileP[X[i]]++;
}
for (int i=1; i<N; i+=2) {
ileA[X[i]]++;
}
if (ile[0] > 0 && ile[2] > 0) {
// nie mogą wystąpić razem 0 i 2, bo drużyna z 2N zawsze wygrywa
return 0;
}
if (ile[1] == N) {
// 1 1 1 ... 1
return policz111(N);
}
// przypadek na 101010, źle zrobiony ale przykładowy test przechodzi
if (ileP[1] == N/2 && ileA[0] == N/2) {
return F[N];
}
if (ileP[2] == N/2 && ileA[1] == N/2) {
return F[N];
}
if (ile[0] == N || ile[2] == N) {
return (F[N*2] * invD[N] - F[N] * 2 - policz111(N)) / 2;
}
return 0;
}
int main()
{
F[0] = 1;
F[1] = 1;
for (int i=2; i<=4000000; ++i) {
F[i] = F[i-1] * i;
}
D[0] = 1; invD[0] = 1;
for (int i=1; i<=4000000; ++i) {
D[i] = D[i-1] * 2;
invD[i] = D[i].inv();
}
int T; scanf("%d", &T);
while (T-->0) {
int N;
scanf("%d", &N); N *= 2;
for (int i=0; i<N; ++i) scanf("%d", &X[i]);
unsigned wynik = dawaj(N).get();
printf("%u\n", wynik);
}
}
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 | #include <cstdio> // *** MODULAR INVERSE CODE FROM https://tfetimes.com/c-modular-inverse/ *** int mul_inv(int a, int b) { int b0 = b, t, q; int x0 = 0, x1 = 1; if (b == 1) return 1; while (a > 1) { q = a / b; t = b, b = a % b, a = t; t = x0, x0 = x1 - q * x0, x1 = t; } if (x1 < 0) x1 += b0; return x1; } const unsigned MOD = 1000000007u; const unsigned long MODL = 1000000007lu; class Mod { unsigned value; public: Mod(int x = 0) : value(x % MOD) { } Mod(unsigned x) : value(x % MOD) { } Mod(unsigned long x) : value(x % MODL) { } Mod operator*(const int x) const { return Mod(static_cast<unsigned long>(value) * static_cast<unsigned long>(x)); } Mod operator*(Mod x) const { return Mod(static_cast<unsigned long>(value) * static_cast<unsigned long>(x.value)); } Mod operator+(Mod x) const { return Mod(static_cast<unsigned long>(value) + static_cast<unsigned long>(x.value)); } Mod operator-(Mod x) const { return Mod(static_cast<unsigned long>(value) + static_cast<unsigned long>(MOD - x.value)); } Mod operator/(Mod x) const { return Mod(static_cast<unsigned long>(value) * static_cast<unsigned long>(mul_inv(x.value, MOD))); } unsigned get() const { return value; } Mod inv() const { return mul_inv(value, MOD); } }; Mod F[4000001]; // n! Mod D[4000001]; // 2^n Mod invD[4000001]; // 1/2^n Mod policz111(int N) { // 1 1 1 ... 1 // karta 2N w jednej drużynie, a 2N-1 w drugiej //return mul_inv(D[N-2].get(), MOD); //return Mod(N) * (N/2) * (N*2-3) * F[N*2-4] * invD[N-2]; return Mod(N) * (N/2) * (N*2-3) * F[N*2-4] * invD[N-2] + Mod(N) * (N/2) * (N/2-1) * (N*2-3) * (N*2-4) * (N*2-5) * F[N*2-6] * invD[N-3]; } int X[1000000]; // N u mnie znaczy liczbę graczy Mod dawaj(int N) { int ile[3] = {0, 0, 0}; int ileA[3] = {0, 0, 0}; int ileP[3] = {0, 0, 0}; for (int i=0; i<N; ++i) { ile[X[i]]++; } for (int i=0; i<N; i+=2) { ileP[X[i]]++; } for (int i=1; i<N; i+=2) { ileA[X[i]]++; } if (ile[0] > 0 && ile[2] > 0) { // nie mogą wystąpić razem 0 i 2, bo drużyna z 2N zawsze wygrywa return 0; } if (ile[1] == N) { // 1 1 1 ... 1 return policz111(N); } // przypadek na 101010, źle zrobiony ale przykładowy test przechodzi if (ileP[1] == N/2 && ileA[0] == N/2) { return F[N]; } if (ileP[2] == N/2 && ileA[1] == N/2) { return F[N]; } if (ile[0] == N || ile[2] == N) { return (F[N*2] * invD[N] - F[N] * 2 - policz111(N)) / 2; } return 0; } int main() { F[0] = 1; F[1] = 1; for (int i=2; i<=4000000; ++i) { F[i] = F[i-1] * i; } D[0] = 1; invD[0] = 1; for (int i=1; i<=4000000; ++i) { D[i] = D[i-1] * 2; invD[i] = D[i].inv(); } int T; scanf("%d", &T); while (T-->0) { int N; scanf("%d", &N); N *= 2; for (int i=0; i<N; ++i) scanf("%d", &X[i]); unsigned wynik = dawaj(N).get(); printf("%u\n", wynik); } } |
English