洛谷题解——P1621 集合
题目相关
题目链接
洛谷,https://www.luogu.com.cn/problem/P1621。
MYOJ,http://47.110.135.197/problem.php?id=5342。
题目描述
Caima 给你了所有 [a,b] 范围内的整数。一开始每个整数都属于各自的集合。每次你需要选择两个属于不同集合的整数,如果这两个整数拥有大于等于 p 的公共质因数,那么把它们所在的集合合并。
重复如上操作,直到没有可以合并的集合为止。
现在 Caima 想知道,最后有多少个集合。
输入格式
一行,共三个整数 a, b, p 用空格隔开。
输出格式
一个数,表示最终集合的个数。
输入样例
10 20 3
输出样例
7
样例解释
对于样例给定的数据,最后有 {10,20,12,15,18},{13},{14},{16},{17},{19},{11} 共 7 个集合,所以输出应该为 7。
数据范围
1 ≤ a ≤ b ≤ 10^5, 2 ≤ p ≤ b。
题解报告
题意分析
解题思路
写出 p 到 b 的所有素数。可以使用欧拉筛,或者最基本的素数判定方法。
逐一遍历这些素数,找出从 a 到 b 之间的倍数,将这些数放在同一个集合中。
样例数据分析
初始化并查集
我们使用 STL 的 map 来保存数据,这样并查集的初始值为:
map<int, int> ds;
ds[10] = 10;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 15;
ds[16] = 16;
ds[17] = 17;
ds[18] = 18;
ds[19] = 19;
ds[20] = 20;
p 到 b 的素数
这样,我们可以写出 p 到 b 的素数为:3, 5, 7, 11, 13, 17, 19。下面我们开始遍历素数,合并集合。
3 的倍数
在 [10, 20] 区间中,3 的倍数有:12, 15, 18。将这三个数变成一个集合 {12, 15, 18}。这样并查查集 ds 变成:
ds[10] = 10;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 12;
ds[16] = 16;
ds[17] = 17;
ds[18] = 12;
ds[19] = 19;
ds[20] = 20;
5 的倍数
ds[10] = 12;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 12;
ds[16] = 16;
ds[17] = 17;
ds[18] = 12;
ds[19] = 19;
ds[20] = 12;
7 的倍数
在 [10, 20] 区间中,7 的倍数有:14。因此这个集合要上上面的集合合并,成为 {14}。这样并查查集 ds 变成:
ds[10] = 12;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 12;
ds[16] = 16;
ds[17] = 17;
ds[18] = 12;
ds[19] = 19;
ds[20] = 12;
11 的倍数
在 [10, 20] 区间中,11 的倍数有:11。因此这个集合要上上面的集合合并,成为 {11}。这样并查查集 ds 变成:
ds[10] = 12;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 12;
ds[16] = 16;
ds[17] = 17;
ds[18] = 12;
ds[19] = 19;
ds[20] = 12;
13 的倍数
在 [10, 20] 区间中,13 的倍数有:13。因此这个集合要上上面的集合合并,成为 {13}。这样并查查集 ds 变成:
ds[10] = 12;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 12;
ds[16] = 16;
ds[17] = 17;
ds[18] = 12;
ds[19] = 19;
ds[20] = 12;
17 的倍数
在 [10, 20] 区间中,17 的倍数有:17。因此这个集合要上上面的集合合并,成为 {17}。这样并查查集 ds 变成:
ds[10] = 12;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 12;
ds[16] = 16;
ds[17] = 17;
ds[18] = 12;
ds[19] = 19;
ds[20] = 12;
19 的倍数
在 [10, 20] 区间中,19 的倍数有:19。因此这个集合要上上面的集合合并,成为 {19}。这样并查查集 ds 变成:
ds[10] = 12;
ds[11] = 11;
ds[12] = 12;
ds[13] = 13;
ds[14] = 14;
ds[15] = 12;
ds[16] = 16;
ds[17] = 17;
ds[18] = 12;
ds[19] = 19;
ds[20] = 12;
到这里位置,我们已经完成并集。下面我们开始遍历 [a, b] 查询其中有几个集合。
查询集合数
根据上面的数据,我们知道 ds[i]=i 表示这是一个集合,因此我们可以统计出集合数为:7。
技术细节
AC 参考代码
//http://47.110.135.197/problem.php?id=5342
//https://www.luogu.com.cn/problem/P1621
//P1621 集合
#include <bits/stdc++.h>using namespace std;map<int, int> ds;
map<int, int> ranks;
vector<int> primes;bool isPrime(int x) {for (int i=2; i*i<=x; i++) {if (0==x%i) {return false;}}return true;
}int find_root(int x) {return x==ds[x]?x:ds[x]=find_root(ds[x]);
}int union_set(int x, int y) {int x_root=find_root(x);int y_root=find_root(y);if (x_root==y_root) {return 0;} else {if (ranks[x_root]>ranks[y_root]) {ds[y_root]=x_root;} else if (ranks[x_root]<ranks[y_root]) {ds[x_root]=y_root;} else {ds[x_root]=y_root;ranks[y_root]++;}return 1;}
}int main() {int a,b,p;cin>>a>>b>>p;//初始化并查集for (int i=a; i<=b; i++) {ds[i]=i;ranks[i]=0;}//列出p到b之间的所有素数for (int i=p; i<=b; i++) {if (true==isPrime(i)) {primes.push_back(i);}}//并集for (int i=0; i<primes.size(); i++) {int st=ceil(1.0*a/primes[i])*primes[i];for (int j=st+primes[i]; j<=b; j+=primes[i]) {union_set(st, j);}}//查询有几个集合int ans=0;for (int i=a; i<=b; i++) {if (ds[i]==i) {ans++;}}cout<<ans<<"\n";return 0;
}
洛谷题解——P1621 集合相关推荐
- 洛谷题解——P2814 家谱
题目相关 题目链接 洛谷,https://www.luogu.com.cn/problem/P2814. MYOJ,http://47.110.135.197/problem.php?id=5344. ...
- 洛谷-题解 P2672 【推销员】
独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...
- 【洛谷题解】P2433 【深基1-2】小学数学 N 合一
目录 [深基1-2]小学数学 N 合一 题解 题目描述 输入格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 题目解析 问题 1~5 问题 6~10 问题 10~14 发牢骚 完整代码 谢谢 ...
- 洛谷题解——P1873:砍树
视频讲解可以直接点击这个 B 站链接,https://www.bilibili.com/video/BV1jk4y1k7hq/. 题目相关 题目链接 洛谷,https://www.luogu.com. ...
- 洛谷题解——P1024:一元三次方程求解
视频讲解可以直接点击这个 B 站链接,https://www.bilibili.com/video/BV1qT4y13717/. 题目相关 题目链接 洛谷,https://www.luogu.com. ...
- 题解系列009 | 洛谷题解 CF488A 【Giga Tower】
原题传送门:Giga Tower 一.题意 题目(传送门)给一个绝对值不超过十位的整数,想计算至多加几后会在和数中出现数字 888. 二.分析 看到这道题,我们最容易想到的当然是暴力枚举,但是首先需要 ...
- 洛谷 P3906 Geodetic集合 题解
题目描述 图G是一个无向连通图,没有自环,并且两点之间至多只有一条边.我们定义顶点v,u最短路径就是从v到u经过边最少的路径.所有包含在v-u的最短路径上的顶点被称为v-u的Geodetic顶点,这些 ...
- 【洛谷题解】P2356 弹珠游戏
本人第一篇题解 今天闲着没事,随机跳题,然后看到这题,觉得运气爆棚,计蒜客L2时空复杂度的课后原题,微改. 首先,这题我们可以知道枚举处理就行,注意点: 1.千万要分清每个数组的用途,不要写错!!本蒟 ...
- 洛谷 P3906 Geodetic集合
题目大意: nnn个点mmm条遍的无向图,如果点iii在点uuu到点vvv的最短路径(uuu到vvv的边数最少)上,那么记这些点为集合I(u,v)I(u,v)I(u,v) 有kkk个询问,问集合I(u ...
最新文章
- libcurl下载限速编程调研
- 名头不小!!VMware vSphere实为VI升级版。
- HDU1978 记忆化搜索
- COJ 0650 绝世难题(一) 可爱的仙人掌
- Dashboard集群
- Mysql 启动失败没日志,MySQL Server 5.7将无法启动,并且未填充错误日志
- 在DataTable和DataView中查找指定记录
- 怎样使用计算机网络,教大家怎样用电脑发出wifi信号,让手机共享!
- vb 获取系统声音的电平_专业音响系统中常见问题,看看你懂几个?
- 0基础Java自学之路
- linux中nmap命令,Linux中nmap命令起什么作用呢?
- 清华山维EPS二次开发VBS基础篇
- 编译原理(整体理解)
- 数据结构与算法学习(第一天)
- 433lora手持机|手持数据采集终端|lora模块手持PDA
- 【郭东白架构课 模块二:创造价值】17|通用技能(下):架构师如何保障交付与沉淀知识?
- 记录一次神奇的大物实验——用模拟法测绘静电场——别人都是打铁~我们打孔~~~
- Google60款开源项目
- Windows下命令行怎样登录MySQL
- 1. Nacos的安装与启动