CF1342E Placing Rooks

题目

给你一个 \(n \times n\) 的棋盘和 \(n\) 个国际象棋中的车。现在要把这 \(n\) 个车摆放在棋盘中。问有多少种摆法,使得恰好有 \(k\) 对车能够相互攻击。

数据范围

\(1 \le n \le 2 \cdot 10^5\)

\(0 \le k \le \frac{n(n-1)}{2}\)

限制

时间:2s

空间:512M

代码

# include <bits/stdc++.h>

using namespace std;
using ll = long long;
const int MOD = 998244353;

ll n, k;

ll qpow(ll base, ll exp)
{
    ll ret = 1;
    while (exp)
    {
        if (exp & 1)
        {
            ret = ret * base % MOD;
        }
        base = base * base % MOD;
        exp >>= 1;
    }

    return ret;
}

int main()
{
    scanf("%lld %lld", &n, &k);

    ll ans = 0;
    if (n > k)
    {
        ll m = n - k;
        ll cmi = 1;
        for (int i = 0; i <= m; ++i)
        {
            ans = (ans + (i % 2 ? -1 : 1) * cmi * qpow(m - i, n)) % MOD;
            cmi = cmi * (m - i) % MOD * qpow(i + 1, MOD - 2) % MOD;
        }
        for (int i = 1; i <= m; ++i)
        {
            ans = ans * (n - i + 1) % MOD * qpow(i, MOD - 2) % MOD;
        }
        if (k != 0)
        {
            ans = ans * 2 % MOD;
        }
        ans = (ans + MOD) % MOD;
    }

    printf("%lld", ans);

    return 0;
}
posted @ 2020-05-27 20:11  Handlip  阅读(140)  评论(0)    收藏  举报