洛谷P1621集合 埃氏筛+并查集
题意:给定a和b和p,若a和b之间的数有>=p的公共素因子,就把a和b所在的集合合并。问最后a,b之间有多少个集合
题目开始理解的不对,一开始还对着样例懵逼:{10,20,12,15,18}怎么能在一个集合?后来看了题解,哦原来只要有两个数有>=p的公共素因子就完事了。比如15和12有3,15和20有5,结果12和20也在同一个集合里。那么用埃氏筛的时候,如果当前的 i 是素数且i>=p,那么在第二层循环 for (j=i+i; j<=b; j+=i)里,把i和j合并就行了。拿样例举例,i=3的时候合并了{12,15,18},i=5的时候又合并成{10,12,15,18,20}
#include<bits/stdc++.h>
using namespace std;
const int maxn=100+10;
int par[maxn];
int find(int x){
if (par[x]==x) return par[x];
else{
par[x]=find(par[x]);
return par[x];
}
}
int main(){
int a,b,p,i,j,n,m;
cin>>a>>b>>p;
for (i=1;i<=b;i++) par[i]=i;
int pr[maxn]={0};
for (i=2;i<=b;i++){
if (!pr[i])
for (j=i+i;j<=b;j+=i){ //***
pr[j]=1;
if (i>=p) {
int findi=find(i);int findj=find(j);
if (findi!=findj) par[findi]=findj; //***
}
}
}
set<int> st;
for (i=a;i<=b;i++) {
par[i]=find(i);
st.insert(par[i]);
}
cout<<st.size()<<endl;
return 0;
}

浙公网安备 33010602011771号