AtCoder Beginner Contest 247 F - Cards // dp + 并查集
题意:
给定N张牌,每张牌正反面各有一个数,所有牌的正面、反面分别构成大小为N的排列P,Q。
求有多少种摆放方式,使得N张牌朝上的数字构成一个1~N的排列。
思路:dp + 并查集
建图:有1~N的顶点,然后Pi跟Qi连一条边。
因为给定的是两个排列,所以每个点的度数为2,因而建出的图必然是由几个独立的环构成。
根据乘法原理,答案就等于每个环的方案数相乘。
求每个环的方案数:
假设环的大小为n(点的数量),dp[n]表示这样的环的方案数:dp[1] = 1,dp[2] = 3,当 n >= 3 时,dp[n] = dp[n - 1] + dp[n - 2]。
上述结论证明:因为每个点都要选出,每个点又跟两条边相连,因此选边时:若此边不选,下条边必须选;若此边已选,下条边可选可不选。那么对于n - 1个点的环,插入第n个点,就由两种情况转移过来。
判环及求环的大小:
并查集可以很好的完成任务 : )
(不得不说并查集真的是简洁又好用的数据结构
代码参考:
//Jakon:dp + 并查集
#include <bits/stdc++.h>
#define int long long
using namespace std; const int mod = 998244353;
const int N = 200010; int n, p[N], q[N], dp[N], fa[N], siz[N]; int find(int x)
{
return fa[x] == x ? x : fa[x] = find(fa[x]);
} signed main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> p[i];
for(int i = 1; i <= n; i++) cin >> q[i]; dp[1] = 1, dp[2] = 3;
for(int i = 3; i <= n; i++) dp[i] = (dp[i - 1] + dp[i - 2]) % mod; for(int i = 1; i <= n; i++) fa[i] = i, siz[i] = 1;
for(int i = 1; i <= n; i++) {
int x = find(p[i]), y = find(q[i]);
if(x != y) fa[x] = y, siz[y] += siz[x];
} int ans = 1;
for(int i = 1; i <= n; i++)
if(fa[i] == i) ans = ans * dp[siz[i]] % mod;
cout << ans << endl; return 0;
}
AtCoder Beginner Contest 247 F - Cards // dp + 并查集的更多相关文章
- AtCoder Beginner Contest 120 D - Decayed Bridges(并查集)
		
题目链接:https://atcoder.jp/contests/abc120/tasks/abc120_d 题意 先给m条边,然后按顺序慢慢删掉边,求每一次删掉之后有多少对(i,j)不连通(我应该解 ...
 - AtCoder Beginner Contest 137 F
		
AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...
 - AtCoder Beginner Contest 182 F
		
F - Valid payments 简化题意:有\(n\)种面值的货币,保证\(a[1]=1,且a[i+1]是a[i]的倍数\). 有一个价格为\(x\)元的商品,付款\(y\)元,找零\(y-x\ ...
 - AtCoder Beginner Contest 261 F // 树状数组
		
题目链接:F - Sorting Color Balls (atcoder.jp) 题意: 有n个球,球有颜色和数字.对相邻的两球进行交换时,若颜色不同,需要花费1的代价.求将球排成数字不降的顺序,所 ...
 - AtCoder Beginner Contest 260 F - Find 4-cycle
		
题目传送门:F - Find 4-cycle (atcoder.jp) 题意: 给定一个无向图,其包含了S.T两个独立点集(即S.T内部间的任意两点之间不存在边),再给出图中的M条边(S中的点与T中的 ...
 - AtCoder Beginner Contest 253 F - Operations on a Matrix // 树状数组
		
题目传送门:F - Operations on a Matrix (atcoder.jp) 题意: 给一个N*M大小的零矩阵,以及Q次操作.操作1(l,r,x):对于 [l,r] 区间内的每列都加上x ...
 - AtCoder Beginner Contest 249 F - Ignore Operations // 贪心 + 大根堆
		
传送门:F - Keep Connect (atcoder.jp) 题意: 给定长度为N的操作(ti,yi). 给定初值为0的x,对其进行操作:当t为1时,将x替换为y:当t为2时,将x加上y. 最多 ...
 - AtCoder Beginner Contest 133 F Colorful Tree
		
Colorful Tree 思路: 如果强制在线的化可以用树链剖分. 但这道题不强制在线,那么就可以将询问进行差分,最后dfs时再计算每个答案的修改值, 只要维护两个数组就可以了,分别表示根节点到当前 ...
 - AtCoder Beginner Contest 132 F Small Products
		
Small Products 思路: 整除分块+dp 打表发现,按整除分块后转移方向如下图所示,上面的块的前缀转移到下面的块 代码: #pragma GCC optimize(2) #pragma G ...
 
随机推荐
- 多级级联数据的展示-vue递归组件
			
如果采用普通的for循环方式,没办法确认数据到底有几层,要写几个for循环,所以想到了递归的方法. 那么在vue里然后实现呢? vue递归组件(组件中使用自己) 父组件中把数据以props形式传给子组 ...
 - JQ的is()
			
is():根据选择器.元素或jQuery对象来检测匹配元素集合, 如果这些元素中至少有一个元素匹配给定的参数,则返回true. <!DOCTYPE html> <html lang ...
 - linux fedora35 配置jdk,安装mysql,安装tomcat
			
配置jdk18很简单,下载jdk,只需要.tar.gz结尾的文件就行,https://download.oracle.com/java/18/latest/jdk-18_linux-x64_bin.t ...
 - Java 16 新特性:record类
			
以前我们定义类都是用class关键词,但从Java 16开始,我们将多一个关键词record,它也可以用来定义类.record关键词的引入,主要是为了提供一种更为简洁.紧凑的final类的定义方式. ...
 - Vue的computed和watch的使用和区别
			
一.computed: 模板内表达式非常便利,可用于简单计算,当模板内放入太多的逻辑时,模板会过重且难以维护:可以使用computed替代 计算属性是基于它们的响应式依赖进行缓存的,当依赖的响应式数据 ...
 - linux篇-修改mysql数据库密码
			
总是忘记,每次都要查文档,背背背 方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = passw ...
 - python面向对象(封装、多态、反射)
			
目录 面向对象之封装 @property 面向对象之多态 面向对象之反射 面向对象之封装 含义 将类中的某些名字按照特殊的书写方式"隐藏"起来,不让外界直接调用,目的是为了不然外界 ...
 - Fail2ban 命令详解 fail2ban-regex
			
fail2ban-regex是fail2ban提供的用来测试正则表达式的一个小工具,我们可以用它来测试正则表达式是否能够匹配到日志文件中的要禁止的IP行. fail2ban-regex默认情况下自动匹 ...
 - 分布式机器学习:逻辑回归的并行化实现(PySpark)
			
1. 梯度计算式导出 我们在博客<统计学习:逻辑回归与交叉熵损失(Pytorch实现)>中提到,设\(w\)为权值(最后一维为偏置),样本总数为\(N\),\(\{(x_i, y_i)\} ...
 - Git合并上的问题
			
关于Git合并上问题的处理 在前几天对某个游戏章节的bug修改完成,主程让我把dev_7的内容合并到dev_8上.虽然很少使用Fork,但是还是硬着头皮说行. 合并前,先将分支切换到dev_8,选择d ...