大力推式子。
容易想到需要满足的条件是:
[sum_i cnt_i mod 2 <= n - 2m
]
好啦我自己想到的部分就到此为止啦
不知道怎么想到的二项式反演:计算钦定有 (i) 种颜色出现了奇数次的方案数 (g_i),一会儿再说怎么转化成“恰好”的方案数。
接下来需要用到生成函数。有一些需要知道的常识(下面均为EGF,下标从0开始):
[<1,1,1,1,1,...>=e^x
]
[<1,-1,1,-1,1>=e^{-x}
]
[large<0,1,0,1,0,1,...>=frac{e^x-e^{-x}}{2}
]
[large e^{ax}=<1,a,a^2,a^3,...>
]
然后有:
[large g_i= {Dchoose i} n![x^n](frac{e^x-e^{-x}}{2})^i(e^x)^{d-i}
]
二项式定理,拆组合数,化为卷积形式:
[=(1/2^i) * {D choose i} n! [x^n]sum_{j}{ichoose j}(e^x)^j(-e^{-x})^{i-j}(e^x)^{D-i}
]
[=frac{D!n!(-1)^i}{(D-i)!2^i}sum_{j}frac{(-1)^j}{j!} * frac{1}{(i-j)!} [x^n]e^{x(2j-2i+D)}
]
[=frac{D!n!(-1)^i}{(D-i)!2^i}sum_{j}frac{(-1)^j}{j!} * frac{1}{(i-j)!} * frac{(D-2(i-j))^n}{n!}
]
[=frac{D!(-1)^i}{(D-i)!2^i}sum_{j}frac{(-1)^j}{j!} * frac{(D-2(i-j))^n}{(i-j)!}
]
[large A_k=frac{(-1)^k}{k!}, B_k=frac{(D-2k)^n}{k!},H_k=A_k*B_k
]
[large g_i=frac{D!(-1)^i}{(D-i)!2^i}h_i
]
这样我们就能够 (O(nlogn)) 求出 (g_i) 了。
然后考虑二项式反演:
[f_k=sum_{i}^D (-1)^{i-k} {ichoose k}g_i
]
[=(1/k!) * sum_{i=0}^D i!g_i * frac{(-1)^{i-k}}{(i-k)!}
]
仍然设 (A_i=i!g_i,B_i=frac{(-1)^i}{i!})
那么:
[f_k=(1/k!) * sum_{i} A_iB_{i-k}
]
这需要一种特殊的卷积。翻转 (B) 数组,即 (B^r_{i}=B_{D-i}),则:
[f_k=(1/k!)sum_iA_iB^r_{D-i+k}
]
这样的话下标之和就是定值 (D+k) 了。
[f_k=(1/k!)C_{D+k}
]
关键代码:
for (register int i = 0; i <= d; ++i) {
if (i & 1) A[i] = P - jieni[i];
else A[i] = jieni[i];
B[i] = quickpow(((d - 2 * i) % P + P) % P, n) * jieni[i] % P;
}
ntt(A, 1), ntt(B, 1);
for (register int i = 0; i < limi; ++i)
h[i] = A[i] * B[i] % P, A[i] = B[i] = 0;
ntt(h, -1);
for (register int i = 0; i <= d; ++i) {
g[i] = (i & 1 ? -1 : 1) * jie[d] * jieni[d - i] % P * quickpow(quickpow(2, i), P - 2) % P * h[i] % P;
if (g[i] < 0) g[i] += P;
}
for (register int i = 0; i <= d; ++i) {
A[i] = jie[i] * g[i] % P;
B[d - i] = (i & 1 ? -1 : 1) * jieni[i] % P;
if (B[d - i] < 0) B[d - i] += P;
}
ntt(A, 1), ntt(B, 1);
for (register int i = 0; i < limi; ++i) f[i] = A[i] * B[i] % P, A[i] = B[i] = 0;
ntt(f, -1);
ll ans = 0;
for (register int k = 0; k <= n - m - m; ++k) {
ans = (ans + jieni[k] * f[d + k]) % P;
}