我是靠谱客的博主 诚心店员,最近开发中收集的这篇文章主要介绍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

#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 1504 整数合并DescriptionInputOutputSample InputSample OutputHintSourceSolutionCodeSummary所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部