Description:
题解:
当k=2的时候就相当于求杨辉三角奇偶性,也就是二次项系数奇偶性,也是格子图方案数。
先把所有坐标减1。
对于(x,y),从(0, 0)走到它的方案数的奇偶性就是它的值,方案数是 Cxx+y=(x+y)!x!y! ,理解是总共有x+y次移动,要向下移动x次的方案数
对于(x,y,z),方案数是 Cx+yx+y+z∗Cxx+y=(x+y+z)!x!y!z!
推广到多维是 (∑ai)!∏ai!
用证明库默尔定理的方法来拆解一下:
(∑ai)!∏ai!mod 2
=∑∞k=0(⌊∑ai2k⌋−∑⌊ai2k⌋)>0
显然有
⌊∑ai2k⌋>=∑⌊ai2k⌋
所以前面的式子的奇偶性相当于:
∑∞k=0⌊∑ai2k⌋!=∑⌊ai2k⌋
此时你发现,如果在二进制的某一位有超过一个 ai 是1,则该式子大于0。
因此
(∑ai)!∏ai!mod 2=∞k=0(∑ai>1)
容斥掉区间,这个直接上数位dp就行了。
#include<cstdio>
#include<cstring>
#define ll long long
#define fo(i, x, y) for(int i = x; i <= y; i ++)
#define fd(i, x, y) for(int i = x; i >= y; i --)
#define w(x, y) ((x & a2[y]) > 0)
using namespace std;
const int mo = 998244353;
int T, n;
ll a2[51], l[10], r[10], b[10];
ll f[51][512], ans;
void dg(int x, int y) {
if(x > n) {
memset(f, 0, sizeof f);
f[50][a2[n] - 1] = 1;
fd(i, 50, 1) {
fo(j, 0, a2[n] - 1) if(f[i][j]) {
int p = 0;
fo(k, 1, n) p += (w(j, k - 1) && !w(b[k], i - 1)) * a2[k - 1];
f[i - 1][p] = (f[i - 1][p] + f[i][j]) % mo;
fo(k, 1, n) {
if(w(j, k - 1) && !w(b[k], i - 1)) continue;
int q = p + w(j, k - 1) * a2[k - 1];
f[i - 1][q] = (f[i - 1][q] + f[i][j]) % mo;
}
}
}
fo(j, 0, a2[n] - 1) ans = (ans + y * f[0][j]) % mo;
return;
}
if(l[x] != 0) b[x] = l[x] - 1, dg(x + 1, -y);
b[x] = r[x];
dg(x + 1, y);
}
int main() {
freopen("warm.in", "r", stdin);
freopen("warm.out", "w", stdout);
a2[0] = 1; fo(i, 1, 50) a2[i] = a2[i - 1] * 2;
for(scanf("%d", &T); T; T --) {
scanf("%d", &n);
fo(i, 1, n) scanf("%lld", &l[i]), l[i] --;
fo(i, 1, n) scanf("%lld", &r[i]), r[i] --;
ans = 0;
dg(1, 1);
ans = (ans + mo) % mo;
printf("%lld\n", ans);
}
}