小兔的话

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


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. DDD中限界上下文与通用语言的作用

    什么是通用语言 通用语言, 最主要的目的就是减少交流中信息丢失, 在实际开发中, 可能关联很多人, 例如有业务层面的业务细节制定者.领域专家.产品经理.项目经理 .架构师.开发经理.测试经理等等, 即 ...

  2. 工作流Activiti框架中表单的使用!详细解析内置表单和外置表单的渲染

    Activiti中的表单 Activiti提供了一种方便而且灵活的方式在业务流程中以手工方式添加表单 对表单的支持有2种方式: 通过表单属性对内置表单进行渲染 通过表单属性对外置表单进行渲染 表单属性 ...

  3. Linux基础服务——Bind DNS服务 Part1

    Linux基础服务--Bind DNS服务 Part1 DNS正向解析 实验环境: CentOS8.3.2011 IP地址:192.168.100.50 VMware虚拟环境 NAT网段 需要解析的区 ...

  4. TensorFlow分布式(多GPU和多服务器)详解

    本文介绍有关 TensorFlow 分布式的两个实际用例,分别是数据并行(将数据分布到多个 GPU 上)和多服务器分配. 玩转分布式TensorFlow:多个GPU和一个CPU展示一个数据并行的例子, ...

  5. cuDNN概述

    cuDNN概述 NVIDIACUDA深度神经网络库(cuDNN)是GPU加速的用于深度神经网络的原语库.cuDNN为标准例程提供了高度优化的实现,例如向前和向后卷积,池化,规范化和激活层. 全球的深度 ...

  6. CodeGen处理Synergy方法目录

    CodeGen处理Synergy方法目录 如果Synergy应用程序开发环境包括使用Synergy/DE xfServerPlus,则可以基于Synergy方法目录中包含的元数据生成代码.要启用此功能 ...

  7. mybatis中sql语句必须用${}而不能不用#{}的情况

    在mybatis中如果我们使用#{}的方式编写的sql时,#{} 对应的变量自动加上单引号 ' ' 例如: select * from #{param} 当我们给参数传入值为user时,他的sql是这 ...

  8. python operator操作符函数

    本模块主要包括一些Python内部操作符对应的函数.这些函数主要分为几类:对象比较.逻辑比较.算术运算和序列操作.

  9. 空指针的解决方案Optional包装类

    有道云笔记地址 (建议有道云打开,markdown文档,直接拷贝过来有一些问题) 引言 在java的开发中,有一个问题始终会伴随着开发的进程.记得我第一个项目的时候,有一个同事在评论我的代码的时候说到 ...

  10. SpringCloud+Docker+Jenkins+GitLab+Maven实现自动化构建与部署实战

    1.前言与初衷 本文章会涉及Docker常见命令基础知识点结合不同场景实操一起使用. 本文章会涉及结合工作过程中部署不同环境服务器的项目案例场景为初心进行实际细讲. 本文章主要讲述Docker.Jen ...