小兔的话

欢迎大家在评论区留言哦~


D - 矩阵

简单题意

一个 \(i * i\) 的 \(01\) 矩阵,若满足 每一行每一列 都满足 恰好 有 \(2\) 个位置是 \(1\) 时,称为 \(i\) 级配对矩阵

设 \(i\) 级配对矩阵的个数为 \(f_i\);请求出:\(\sum_{i = 1}^n f_i\),答案对 \(998244353\) 取模

数据范围

\(1 \leq n \leq 10^7\)

知识点

  • 动态规划(\(dp\))

分析

题意转换

这个题目有点复杂,换成一个能更好理解题目解析的:

有一个长度为 \(i\) 的序列,初始状态时全部的数都为 \(0\)

有 \(i\) 次操作,每一次操作需要选择 \(2\) 个不同的位置,并把其所对应的数 \(+1\)

\(f_i\) 定义为能使原序列的数全部变成 \(2\) 的操作方案数;请求出:\(\sum_{i = 1}^n f_i\),答案对 \(998244353\) 取模

  • 矩阵有 \(i\) 列 \(\to\) 长度为 \(i\) 的序列
  • 每一行的 \(1\) 的 \(2\) 个位置 \(\to\) 选择 \(2\) 个位置 \(+1\)
  • 矩阵有 \(i\) 行 \(\to\) \(i\) 次操作
  • 每一列都恰好满足有 \(2\) 个位置是 \(1\) \(\to\) 使原序列的数全部变成 \(2\)
  • 每一列的 \(1\) 的 \(2\) 个位置 \(\to\) 该位置对应的 \(2\) 次 \(+1\) 操作

题目解析

  • 特殊说明:\(dp_i\) 表示原题目中的 \(f_i\);\(A\) 表示排列数;\(C\) 表示组合数
  • 特殊说明:\(F_i\) 表示序列中已经进行了 \(1\) 次操作的方案数(即有 \(2\) 个位置已经是 \(1\) 了,剩下 \(i-1\) 次操作)

对于一个长度为 \(i\) 的空序列,考虑某个位置的 \(2\) 次操作

不妨考虑位置 \(1\)(任意一个都可以)的 \(2\) 次操作,这 \(2\) 次操作对位置 \(1\) 的总贡献是一样的(使位置 \(1\) 的数变为 \(2\)),就可以转换为其余 \(i-1\) 个位置中 \(2\) 个位置(可以相同)的 \(+1\) 操作,接下来讨论操作的位置(其余的 \(i-1\) 个)及其贡献(\(dp\)):

  • \(2\) 次操作影响相同位置:\(dp_{i-2} \times (i-1) \times C_i^2\)

    • \(dp_{i-2}\):因为 \(2\) 次选择的是相同位置,那么就需要考虑剩下的 \(i-2\) 个位置的贡献
    • \(i-1\):位置的可能性,有 \(i-1\) 个位置可选择操作
    • \(C_i^2\):因为操作的顺序是会影响结果的,所以需要计算 \(2\) 次操作的可能性;有 \(i\) 个操作位置,选择其中的 \(2\) 次,又因为这 \(2\) 次操作是等价的所以是 \(C_i^2\)
  • \(2\) 次操作影响不同位置:\(F_{i-1} \times C_{i-1}^2 \times A_i^2\)
    • \(F_{i-1}\):\(2\) 次操作影响不同位置,相当于 \(i-1\) 个位置中有 \(2\) 个已经 \(+1\) 了
    • \(C_{i-1}^2\):在 \(i-1\) 个位置中选 \(2\) 个(不计顺序)
    • \(A_i^2\):在 \(i\) 次操作选择 \(2\) 次进行不等价操作

接下来分析 \(F\):

  • 用 \(1\) 次操作把 \(1\) 对应的 \(2\) 个位置变成 \(2\):\(dp_{i-2} \times (i-1)\)

    • \(dp_{i-2}\):除去这 \(2\) 个位置的方案数
    • \(i-1\):在 \(i-1\) 次操作中选择 \(1\) 次
  • 用 \(2\) 次操作把 \(1\) 对应的 \(2\) 个位置变成 \(2\),同时把另外 \(1\) 个位置变为 \(2\):\(dp_{i-3} \times (i-2) \times A_{i-1}^2\)
    • \(dp_{i-3}\):除去这 \(3\) 个位置的方案数
    • \(i-2\):另外 \(1\) 个位置可能有 \(i-2\) 中可能
    • \(A_{i-1}^2\):在 \(i-1\) 次操作中选择 \(2\) 次进行不等价操作
  • 用 \(2\) 次操作把 \(1\) 对应的 \(2\) 个位置变成 \(2\),同时把另外 \(2\) 个位置变为 \(1\):\(F_{i-2} \times A_{i-2}^2 \times A_{i-1}^2\)
    • \(F_{i-2}\):剩下 \(i-2\) 个中有 \(2\) 个已经位 \(1\) 的方案数
    • \(A_{i-2}^2\):在 \(i-2\) 个位置中选择 \(2\) 个变成 \(1\),与现在的 \(2\) 个位置匹配是不等价的,所以是 \(A\)
    • \(A_{i-1}^2\):在 \(i-1\) 次操作中选择 \(2\) 次进行不等价操作

初始化:\(dp_0 = 1, dp_2 = 1, F_2 = 1\),其余值为 \(0\)

循环枚举 \(i\),进行状态转移,顺便求出 \(\sum_{i=1}^n dp_i\) 就可以了(这种做法似乎常数很大,不建议使用 C++(NOI)

代码

#include <cstdio>

#define int long long

int rint()
{
int x = 0, fx = 1; char c = getchar();
while (c < '0' || c > '9') { fx ^= (c == '-'); c = getchar(); }
while ('0' <= c && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = getchar(); }
if (!fx) return -x;
return x;
} int qpow(int u, int v, int Mod)
{
int res = 1;
while (v)
{
if (v & 1LL) res = res * u % Mod;
u = u * u % Mod; v >>= 1;
}
return res;
} const int MOD = 998244353;
const int MAX_n = 1e7; int ans, dp[MAX_n + 5], F[MAX_n + 5];
int FAC[MAX_n + 5], inv[MAX_n + 5]; int A(int n, int m) { return FAC[n] * inv[n - m] % MOD; }
int C(int n, int m) { return A(n, m) * inv[m] % MOD; } signed main()
{
freopen("matrix.in", "r", stdin);
freopen("matrix.out", "w", stdout);
int n = rint();
FAC[0] = 1;
for (int i = 1; i <= n; i++)
FAC[i] = FAC[i - 1] * i % MOD;
inv[n] = qpow(FAC[n], MOD - 2, MOD);
for (int i = n; i >= 1; i--)
inv[i - 1] = inv[i] * i % MOD;
dp[0] = 1; dp[2] = 1; F[2] = 1;
for (int i = 3; i <= n; i++)
{
dp[i] = (dp[i] + dp[i - 2] * C(i, 2) % MOD * (i - 1) % MOD) % MOD;
dp[i] = (dp[i] + F[i - 1] * A(i, 2) % MOD * C(i - 1, 2) % MOD) % MOD;
F[i] = (F[i] + dp[i - 2] * (i - 1) % MOD) % MOD;
F[i] = (F[i] + F[i - 2] * A(i - 1, 2) % MOD * A(i - 2, 2) % MOD) % MOD;
F[i] = (F[i] + dp[i - 3] * A(i - 1, 2) % MOD * (i - 2) % MOD) % MOD;
}
for (int i = 1; i <= n; i++) ans = (ans + dp[i]) % MOD;
printf("%lld\n", ans);
return 0;
}

「 题解」NOIP2021模拟赛(2021-07-19)的更多相关文章

  1. 「NOWCODER」CSP-S模拟赛第3场

    「NOWCODER」CSP模拟赛第3场 T1 货物收集 题目 考场思路即正解 T2 货物分组 题目 考场思路 题解 60pts 算法:一维 DP 100pts 算法:一维 DP ?线段树 + 单调栈 ...

  2. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  3. 「题解」NOIP模拟测试题解乱写I(29-31)

    NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...

  4. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  5. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  6. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  7. 2021.07.19 P2294 狡猾的商人(差分约束)

    2021.07.19 P2294 狡猾的商人(差分约束) [P2294 HNOI2005]狡猾的商人 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.差分约束最长路与最短 ...

  8. 2021.07.19 P2624 明明的烦恼(prufer序列,为什么杨辉三角我没搞出来?)

    2021.07.19 P2624 明明的烦恼(prufer序列,为什么杨辉三角我没搞出来?) [P2624 HNOI2008]明明的烦恼 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn ...

  9. 2021.07.19 BZOJ2654 tree(生成树)

    2021.07.19 BZOJ2654 tree(生成树) tree - 黑暗爆炸 2654 - Virtual Judge (vjudge.net) 重点: 1.生成树的本质 2.二分 题意: 有一 ...

随机推荐

  1. Java设计模式(2:单一职责原则和依赖倒置原则详解)

    一.单一职责原则 不要存在多于一个导致类变更的原因.简单来说,就是一个Class/Interface/Method只负责一项职责. 这句话最为重要的就是这一段:一个Class/Interface/Me ...

  2. TensorFlow分布式在Amazon AWS上运行

    TensorFlow分布式在Amazon AWS上运行 Amazon AWS 提供采用 NVIDIA K8 GPU 的 P2.x 机器.为了能够使用,第一步还需要创建一个 Amazon AWS 账户, ...

  3. 图分析Rapids cuGraph

    图分析Rapids cuGraph 英伟达(Nvidia)建立的新的开源库可能是推进分析和使图形数据库更快的秘密要素. 在Nvidia GPU上进行并行处理. Nvidia很久以前就不再只是" ...

  4. 理想的GVS智能照明体验,就在汕头迎宾花园酒店

    汕头,依海而生,海在城中央是汕头特色. 汕头湾将汕头分为南北两岸,造就绝美市区海岸线,一碧万顷的海湾,焕然一新的海港,在市区就能直接看海. 在北山湾,动可结伴冲浪,静可观海吹风,动静都是一种快乐. 当 ...

  5. Appium UI自动化测试

    #coding:utf-8 from appium import webdriver import time,traceback ''' desired_capabilities:这些键告诉appiu ...

  6. Jenkins 进阶篇 - 数据备份

    随着我们的长期使用,Jenkins 系统中的内容会越来越多,特别是一些配置相关的东西,不能有任何丢失.这个时候我们就需要定期备份我们的 Jenkins 系统,避免一些误操作不小心删除了某些重要文件,J ...

  7. 【NX二次开发】Block UI 树列表

    属性说明 属性   类型   描述   常规           BlockID    String    控件ID    Enable    Logical    是否可操作    Group    ...

  8. 04:Django生命周期流程图

  9. 聚类算法K-Means算法和Mean Shift算法介绍及实现

    Question:什么是聚类算法 1.聚类算法是一种非监督学习算法 2.聚类是在没有给定划分类别的情况下,根据数据相似度进行样本分组的一种方法 3.理论上,相同的组的数据之间有相同的属性或者是特征,不 ...

  10. Redis哨兵的配置和原理

    哨兵 在一个典型的一主多从的Redis系统中,当主数据库遇到异常中断服务后,需要手动选择一个从数据库升级为主数据库,整个过程需要人工介入,难以自动化. Redis2.8提供了哨兵2.0(2.6提供了1 ...