Codeforces 1342 E. Placing Rooks(容斥)

在这里插入图片描述
在这里插入图片描述

题意:

在一个 n ∗ n n*n nn 的棋盘上放置 n n n 个车,满足以下两个条件:

  1. 棋盘上的每一个空格子都能被至少一只车走到
  2. 恰好存在 k k k 对车可以相互攻击

求所有车的摆放方案数。

要满足第一个条件,则每一行/每一列都有一个车,两者至少满足其一。对于这两种情况是等价的,下面只考虑每一行都有车,最终结果乘 2 2 2 即可, k = 0 k=0 k=0 不需要 ∗ 2 *2 2

假设所有行都有一个车,把每一列单独考虑,如果一列放了 x x x 个车,那么一定会产生 x − 1 x-1 x1 对,在满足情况的条件下,恰好有 k k k 列是空的,这个可以自己画一下。

那就是棋子都放到 n − k n−k nk 列,一共 ( n − k ) n (n−k)^n (nk)n 种情况,减去至少有 1 1 1 个空行的情况 ( n − k − 1 ) n C n − k 1 (n−k−1)^nC^1_{n−k} (nk1)nCnk1 ,加上至少有 2 个空行的情况 ( n − k − 2 ) n C n − k 2 (n−k−2)^nC^2_{n−k} (nk2)nCnk2,减去至少有 3 个空行 ( n − k − 3 ) n C n − k 3 (n−k−3)nC^3_{n−k} (nk3)nCnk3 ,……经典容斥模型。

AC代码:

const int N = 2e5 + 10;
const int mod = 998244353;
ll fac[N];
int n, k;
void init()
{
	fac[0] = 1;
	rep(i, 1, N - 2)
		fac[i] = fac[i - 1] * i % mod;
}

ll c(int x, int y)
{
	return fac[x] * qpow(fac[y] * fac[x - y] % mod, mod - 2, mod) % mod;
}

int main()
{
	init();
	sdd(n, k);
	if (k == 0)
	{
		pld(fac[n]);
		return 0;
	}
	if (k >= n)
	{
		puts("0");
		return 0;
	}
	ll ans = 0;
	rep(i, 0, n - k)
		ans += 1ll * qpow(mod - 1, i,mod) * c(n - k, i) % mod * qpow(n - k - i, n,mod) % mod;
	ans %= mod;
	ans = 2ll * ans % mod * c(n, n - k) % mod;
	pld(ans);
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值