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

 

posted @ 2017-10-16 20:12  Aptal丶  阅读(256)  评论(0编辑  收藏  举报