洛谷——P1621 集合
https://www.luogu.org/problem/show?pid=1621
题目描述
现在给你一些连续的整数,它们是从A到B的整数。一开始每个整数都属于各自的集合,然后你需要进行一下的操作:
每次选择两个属于不同集合的整数,如果这两个整数拥有大于等于P的公共质因数,那么把它们所在的集合合并。
反复如上操作,直到没有可以合并的集合为止。
现在Caima想知道,最后有多少个集合。
输入输出格式
输入格式:
一行,三个整数A,B,P。
【数据规模】
A≤B≤100000;
2≤P≤B。
输出格式:
一个数,表示最终集合的个数。
输入输出样例
输入样例#1:
10 20 3
输出样例#1:
7
说明
有80%的数据B≤1000。
样例解释{10,20,12,15,18},{13},{14},{16},{17},{19},{11}。
欧拉筛练习
1 #include <cstdio> 2 3 inline void read(int &x) 4 { 5 x=0; register char ch=getchar(); 6 for(; ch>'9'||ch<'0'; ) ch=getchar(); 7 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 8 } 9 10 const int N(100005); 11 int A,B,P; 12 13 bool not_pri[N],out[N]; 14 int prime[N],cnt; 15 inline void Prime() 16 { 17 for(int i=2; i<=B; ++i) 18 { 19 if(!not_pri[i]) prime[++cnt]=i; 20 for(int j=1; j<=cnt; ++j) 21 { 22 if(i*prime[j]>B) break; 23 not_pri[i*prime[j]]=1; 24 if(i%prime[j]==0) break; 25 } 26 } 27 } 28 29 int fa[N],ans; 30 int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); } 31 32 int Presist() 33 { 34 read(A),read(B),read(P); Prime(); 35 for(int i=1; i<=B; ++i) fa[i]=i; 36 for(int dad,i=P; i<=B; ++i) 37 { 38 if(not_pri[i]) continue; 39 dad=find(i); 40 for(int j=2; j*i<=B; ++j) 41 { 42 if(j*i<A) continue; 43 fa[find(j*i)]=dad; 44 } 45 } 46 for(int home,i=A; i<=B; ++i) 47 { 48 home=find(i); 49 ans+=(!out[home]); 50 out[home]=1; 51 } 52 printf("%d\n",ans); 53 return 0; 54 } 55 56 int Aptal=Presist(); 57 int main(int argc,char**argv){;}
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。