ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解:LuoguP4921 情侣?给我烧了

2022-07-22 08:33:36  阅读:160  来源: 互联网

标签:LuoguP4921 题解 LL 情侣 times choose inv mod


题解:LuoguP4921 情侣?给我烧了

[MtOI2018]情侣?给我烧了! - 洛谷

题意简述

有 \(n\) 对情侣,\(2\) 列座位,座位共有 \(n\) 排。

求恰有 \(k\) 对情侣坐在了同一排座位上的方案数。

\(T\le 1000\) 组数据,每组数据给出一个整数 \(n\le 1000\) ,输出 \(k=0\sim n\) 时 的答案。

思路

设 \(G_K\) 表示恰好选择 \(k\) 对情侣坐在一排的方案数(\(k\) 对情侣已经确定)

\(F_k\) 表示选择 \(k\) 对情侣坐在一排的方案数(\(k\) 对情侣也已确定)

设任意 \(k\) 对情侣坐在一排的方案数(待求答案)为 \(ans_k\) 。

那么有 \(ans_k={n\choose k}^2\times k!\times 2^k\times D_{n-k}\)

座位选择*情侣选择*座位之间的排列*情侣二人之间互换位置*剩下n-k对情侣都不在座位上的"错排"

\(D_n\) 表示 \(2n\) 个座位,\(n\) 对情侣都不坐一起的方案数,显然 \(D_n\) = \(G_0\),

易知 \(F_k={n\choose k}^2\times k!\times 2^k\times (2(n-k))!\)

因为 \(F_k=\sum_{i=k}^{n}{{i\choose k}G(k)}\) ,(\(i\choose k\) 表示 \(i\) 对情侣选出确定的 \(k\) 对)。

观察到上式是二项式反演的标准形式之一,于是有:

\(G_k=\sum_{i=k}^{n}{(-1)^{i-k}}{i\choose k}F_i\)

解得: \(D_n=G_0=\sum_{i=0}^{n}{(-1)^{i}{n\choose i}^2}\times i!\times 2^i\times (2(n-i))!\) 。

带入原式 \(ans_k\) 即可。

最终解得:

\(ans_k={n\choose k}^2\times k!\times 2^k\times D_{n-k}\)

\(D_n=\sum_{i=0}^{n}{(-1)^{i}{n\choose i}^2}\times i!\times 2^i\times (2(n-i))!\)

#include <bits/stdc++.h>
const int N = 2050, mod = 998244353;
using LL = long long;
auto sign = [](int x)
    -> LL{ return (x & 1) ? -1 : 1; };
auto mul = [](LL a, LL b, LL c, LL d, LL e)
    -> LL{ return ((((a * b % mod) * c % mod) * d) % mod * e) % mod; };
LL inv[N], fac[N], D[N], pow2[N];
LL C(int x, int y) { return fac[x] * inv[y] % mod * inv[x - y] % mod; }
void init()
{
    fac[1] = inv[1] = fac[0] = inv[0] = pow2[0] = 1;
    pow2[1] = 2;
    for (int i = 2; i < N; i++)
        inv[i] = (mod - mod / i) * inv[mod % i] % mod,
        fac[i] = fac[i - 1] * i % mod,
        pow2[i] = (pow2[i - 1] << 1) % mod;
    for (int i = 2; i < N; i++)
        inv[i] = inv[i] * inv[i - 1] % mod;
    for (int n = 0; n < (N >> 1); n++)
        for (int i = 0; i <= n; i++)
            D[n] = (D[n] + sign(i) * mul(C(n, i), C(n, i), fac[i], pow2[i], fac[(n - i) << 1]) + mod) % mod;
}

int main()
{
    int T;
    scanf("%d", &T);
    init();
    while (T--)
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i <= n; i++)
            printf("%lld\n", mul(C(n, i), C(n, i), fac[i], pow2[i], D[n - i]));
    }
    return 0;
}

标签:LuoguP4921,题解,LL,情侣,times,choose,inv,mod
来源: https://www.cnblogs.com/mklzc/p/16504297.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有