洛谷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;
}

  

原文地址:https://www.cnblogs.com/edmunds/p/12357092.html