abc247_f Cards 题解
Cards
题意
有
同时,
我们需要在
请求出选卡片的方法数,答案对
数据范围
, 和 是 的全排列。
思路
这题需要一定的联想能力。
首先,这些卡牌可以看作构成了一个图,每次将
环与环之间都是独立的,所以要用乘法原理。
问题是,怎样求出每个环的方案数呢?
首先,我们有一个小小的环。
然后,我们先来整一个 dp
:
- 环的大小为
,令大小为 的环的方案数为 。 ,边 和边 都不选,不合法。 ,选边 而不选边 , 。 ,选边 而不选边 , ,边 和 都选。
- 那么,
(备注: ) - 特别的,通过手推我们发现
。
复杂度
- 时间:
- 空间:
Code
点击查看代码
#include <iostream> using namespace std; const int N = 2e5 + 10, mod = 998244353; int n, a[N], b[N], f[N], dp[N]; long long ans = 1; int dfs (int x) { // 找环 if (f[x]) { // 找到重复点了 return 0; } f[x] = 1; return dfs(b[x]) + 1; } int main () { ios::sync_with_stdio(0), cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { cin >> b[a[i]]; } dp[1] = 1, dp[2] = 3; // f数组的递推 for (int i = 3; i <= n; i++) { dp[i] = (dp[i - 1] + dp[i - 2]) % mod; // 记得取模 } for (int i = 1; i <= n; i++) { if (!f[i]) { ans = ans * dp[dfs(i)] % mod; // 乘法原理 } } cout << ans; return 0; }
本文作者:wnsyou の blog
本文链接:https://www.cnblogs.com/wnsyou-blog/p/17311509.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步