我是靠谱客的博主 诚心店员,这篇文章主要介绍CJOJ 1504 整数合并DescriptionInputOutputSample InputSample OutputHintSourceSolutionCodeSummary,现在分享给大家,希望可以做个参考。
整数合并
Description
现在给你一些连续的整数,它们是从 A 到 B 的整数。一开始每个整数都属于各自的集合,然后你需要进行如下操作:
每次选择两个属于不同集合的整数,如果这两个整数拥有大于等于 P 的公共质因子,那么把他们所在的集合合并。
反复上述操作,直到没有可以合并的集合为止。
现在,小 X 想知道,最后有多少个集合。
Input
一行,三个整数 A,B,P
Output
一个数,表示最终集合的个数。
Sample Input
10 20 3
Sample Output
7
Hint
样例解释:
解释: {10 , 20 , 12 , 15 , 18} , {11},{13} , {14} , {16} , {17} , {19}
【数据规模】
B<=1000. 80%数据
A<=B<=100000; 2<=P<=B
Source
并查集 ,数学 ,数论
Solution
对于有相同质因数的数字加入一个集合,最后统计集合的个数即可(爸爸是自己的点的个数)
Code
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <stack> #include <map> #include <vector> #include <queue> #define L 100010 #define LL long long using namespace std; int a, b, p, prim[L], cnt, f[L], ans; bool check[L]; inline int find(int x) { return (f[x] == x) ? x : f[x] = find(f[x]);} inline void makeset(int x, int fa) {f[find(x)] = f[find(fa)];} int main() { freopen("CJOJ1504.in", "r", stdin); freopen("CJOJ1504.out", "w", stdout); scanf("%d %d %d", &a, &b, &p); for (int i = a; i <= b; ++i) f[i] = i; for (int i = 2; i <= b; ++i) { if (!check[i]) prim[++cnt] = i; for (int j = 1; j <= cnt && i * prim[j] <= b; ++j) { check[prim[j] * i] = 1; if (i % prim[j] == 0) break; } } for (int i = 1; i <= cnt; ++i) if (prim[i] >= p) { int c = a / prim[i] * prim[i]; if (c != a) c += prim[i]; for (int j = c + prim[i]; j <= b; j += prim[i]) makeset(j, c); } for (int i = a; i <= b; ++i) if (f[i] == i) ans++; printf("%dn", ans); return 0; }
Summary
注意合并集合的时候试讲他们的父亲放在一起,以及初始化的时候初始自己的父亲是自己
最后
以上就是诚心店员最近收集整理的关于CJOJ 1504 整数合并DescriptionInputOutputSample InputSample OutputHintSourceSolutionCodeSummary的全部内容,更多相关CJOJ内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复