• CF1342E Placing Rooks 题解


    题面

    第一个条件等价于:每一行都有车 / 每一列都有车。

    不妨设每一行都有车,最后算答案时 ( imes 2) 即可。

    有一个结论:如果恰好 (m) 列有车,那么就有 (n-m) 对车互相攻击。证明显然。

    那么就可以知道恰好有 (n-k) 列有车。

    于是考虑容斥,设在 (n-k) 列中有 (i) 列为空,则最终答案式子为:

    [2 imesinom{n}{n-k} imessumlimits_{i=0}^{n-k}(-i)^i(n-k-i)^ninom{n-k}{i} ]

    代码:

    #include <bits/stdc++.h>
    #define DC int T = gi <int> (); while (T--)
    #define DEBUG fprintf(stderr, "Passing [%s] line %d
    ", __FUNCTION__, __LINE__)
    #define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    
    using namespace std;
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair <int, int> PII;
    typedef pair <LL, LL> PLL;
    
    template <typename T>
    inline T gi()
    {
    	T x = 0, f = 1; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return f * x;
    }
    
    const int N = 200003, M = N << 1, mod = 998244353;
    
    int n;
    LL k;
    int fac[N], invfac[N];
    
    inline int qpow(int x, int y)
    {
    	int res = 1;
    	while (y)
    	{
    		if (y & 1) res = 1ll * res * x % mod;
    		x = 1ll * x * x % mod, y >>= 1;
    	}
    	return res;
    }
    
    inline int C(int x, int y)
    {
    	if (x < 0 || y < 0 || x < y) return 0;
    	return 1ll * fac[x] * invfac[y] % mod * invfac[x - y] % mod;
    }
    
    int main()
    {
    	//freopen(".in", "r", stdin); freopen(".out", "w", stdout);
    	n = gi <int> (), k = gi <LL> ();
    	if (k >= n) return puts("0"), 0;
    	for (int i = (fac[0] = 1); i <= n; i+=1) fac[i] = 1ll * fac[i - 1] * i % mod;
    	invfac[n] = qpow(fac[n], mod - 2);
    	for (int i = n - 1; i >= 0; i-=1) invfac[i] = 1ll * invfac[i + 1] * (i + 1) % mod;
    	if (!k) return printf("%d
    ", fac[n]), 0;
    	int sum = 0;
    	for (int i = 0, t = 1; i <= n - k; i+=1, t *= -1)
    	{
    		int tmp = 1ll * qpow(n - k - i, n) * C(n - k, i) % mod;
    		tmp *= t;
    		(sum += tmp) %= mod;
    	}
    	(sum += mod) %= mod;
    	sum = 2ll * sum % mod * C(n, n - k) % mod;
    	printf("%d
    ", sum);
    	return !!0;
    }
    
  • 相关阅读:
    Processing编程【2】
    哈工大锐捷网络处理问题
    processing编程【1】
    verilog入门知识【2】
    数字电路与逻辑设计知识清单【一】
    四位密码锁*电子密码锁的设计
    verilog入门知识【1】
    【Android】入门的一些知识。
    Andriod 入门
    关于Hibernate和Strtus2的xml提示问题
  • 原文地址:https://www.cnblogs.com/xsl19/p/15505549.html
Copyright © 2020-2023  润新知