set
【题目描述】
现在给你一些连续的整数,它们是从 到 的整数。一开始每个整数都属于各自的集合,然后你需要进行如下操作:每次选择两个属于不同集合的整数,如果这两个整数拥有大于等于 的公共质因数,那么把它们所在的集合合并。反复上述操作,直到没有可以合并的集合为止。现在 想知道,最后有多少个集合。
【输入格式】
一行,三个整数 ,,。
【输出格式】
一个数,表示最终集合的个数。
【数据规模】
;
。
【输入样例】
10 20 3
【输出样例】
7 【注意事项】
有 % 的数据 。 样例解释{10,20,12,15,18},{13},{14},{16},{17},{19}。
#include<bits/stdc++.h>
using namespace std;
int fa[111111];
int find(int x) {//递归
if(x!=fa[x]) {
fa[x]=find(fa[x]);
}
return fa[x];
}
void merge(int aa,int bb) {
int a=find(aa);
int b=find(bb);
if(a!=b) fa[b]=a;
}
int prime[111111],t[111111],a,b,p;
int main() {
cin>>a>>b>>p;
for(int i=a;i<=b;i++) {
fa[i]=i;
}
for(int i=2;i<=b;i++) {
if(!prime[i])
for(int j=2;j*i<=b;j++) {
prime[i*j]=1;
if(i>=p&&i*j-i>=a) {
merge(j*i,j*i-i);
// cout<<i<<" "<<j*i<<" "<<j*i-i<<"\n";
}
}
}
// cout<<"------------";
for(int i=a;i<=b;i++) {
t[find(i)]=1;
// cout<<find(i)<<":"<<i<<"\n";
}
int ans=0;
for(int i=a;i<=b;i++) {
ans+=t[i];
}
cout<<ans;
return 0;
}
题意
给你一段连续的正整数,如果有共同的质因数,就合并。
求最后会合并成多少种。
思路
一看见“合并”,很明显的特征就是并查集。
至于质因数,也可以联想到质数筛选。
对于 ≥p 的质因数

浙公网安备 33010602011771号