QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#579147#6884. Number TablechangziliangAC ✓0ms3952kbC++141.9kb2024-09-21 09:43:282024-09-21 09:43:28

Judging History

你现在查看的是最新测评结果

  • [2024-09-21 09:43:28]
  • 评测
  • 测评结果:AC
  • 用时:0ms
  • 内存:3952kb
  • [2024-09-21 09:43:28]
  • 提交

answer

// 一维dp, 二维容斥 
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
typedef long long LL;
const LL mod = 998244353;
int T, n, k;
LL f[N], m, c[N][N], inv[N], fac[N];
inline LL Pow(LL x, LL y) {
	LL res = 1LL, k = x;
	while(y) {
		if(y & 1) res = res * k % mod;
		y >>= 1;
		k = k * k % mod;
	}
	return res;
}
LL C(int k, LL n, int m) {
	if(k <= 7 && n < m) return 0;
	LL res = 1LL;
	for(LL i = n; i > n - m; i -- ) {
		res = (res * i % mod + mod) % mod;
	}
	res = res * inv[m] % mod;
	return res;
}
LL A(int n, int m) {
	if(n < m) return 0;
	return fac[n] * inv[n - m] % mod;
}
inline LL F(int x) {return (x & 1) ? mod - 1LL : 1LL;}
LL solve(int n, int k) {
	f[1] = f[0] = 1LL; m = Pow(2LL, 1LL * k);
	for(int i = 2; i <= n * 2; i ++ ) {
		LL tmp = 1LL;
		for(int j = m; j >= m - i + 2; j -- ) tmp = tmp * 1LL * j % mod;
		tmp = ((tmp - 1LL * (i - 1) * (m - 1LL * i + 2LL) % mod * f[i - 2] % mod) % mod + mod) % mod;
		f[i] = tmp;
	}
	LL res = 0;
	for(int i = 0; i <= n; i ++ ) { // 对列的限制进行容斥 
		int ct = n - i;
		LL tmp = F(i) * c[n][i] % mod * fac[i] % mod, g = 0;
		for(int j = 0; j <= ct; j ++ ) { // 枚举相同的数的数量 
			g = (g + f[2 * ct - 2 * j] * C(k, m - 2LL * (ct - j), j) % mod * A(ct, j) % mod * A(ct, j) % mod * C(k, m - 2LL * n + 2LL * i + j, i) % mod) % mod;
		}
		res = (res + tmp * g % mod) % mod;
	}
	return res;
}
int main() {
	for(int i = 0; i < N; i ++ ) {
		for(int j = 0; j <= i; j ++ ) {
			if(!j) c[i][j] = 1LL;
			else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
		}
	}
	fac[0] = 1LL;
	for(int i = 1; i <= 40; i ++ ) fac[i] = fac[i - 1] * 1LL * i % mod;
	inv[40] = Pow(fac[40], mod - 2LL);
	for(int i = 39; i >= 0; i -- ) inv[i] = inv[i + 1] * 1LL * (i + 1) % mod;
	scanf("%d", &T);
	while(T -- ) {
		scanf("%d%d", &n, &k);
		printf("%lld\n", solve(n, k));
	}
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3952kb

input:

10
1 1
2 1
2 2
3 3
5 3
10 10
10 15
10 20
39 3912
40 4512

output:

0
2
36
8736
2876160
904592472
797736012
373557465
587036386
203956590

result:

ok 10 lines