标签:name 一个 大于 输出 集合 ++ cstring not include
现在给你一些连续的整数,它们是从A到B的整数。一开始每个整数都属于各自的集合,然后你需要进行一下的操作:
每次选择两个属于不同集合的整数,如果这两个整数拥有大于等于P的公共质因数,那么把它们所在的集合合并。
反复如上操作,直到没有可以合并的集合为止。
现在Caima想知道,最后有多少个集合。
输入格式:
一行,三个整数A,B,P。
【数据规模】
A≤B≤100000;
2≤P≤B。
输出格式:
一个数,表示最终集合的个数。
10 20 3
7
有80%的数据B≤1000。
样例解释{10,20,12,15,18},{13},{14},{16},{17},{19},{11}。
欧拉筛+并查集
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 100002 using namespace std; bool not_prime[N],vis[N]; int A,B,p,fx,tot,ans,fa[N],prime[N]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } int Euler_sieve() { for(int i=2;i<=B;i++) { if(!not_prime[i]) prime[++tot]=i; for(int j=1;j<=tot;j++) { if(i*prime[j]>B) break; not_prime[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int find(int x) { if(fa[x]==x) return x; fa[x]=find(fa[x]); return fa[x]; } int main() { A=read(),B=read(),p=read(); Euler_sieve(); for(int i=1;i<=B;i++) fa[i]=i; for(int i=p;i<=B;i++) if(!not_prime[i]) { fx=find(i); for(int j=2;j<=B;j++) { if(i*j>B) break; if(i*j<A) continue; fa[find(i*j)]=fx; } } for(int i=A;i<=B;i++) if(!vis[find(i)]) ans++,vis[find(i)]=true; printf("%d",ans); return 0; }
标签:name 一个 大于 输出 集合 ++ cstring not include
原文地址:http://www.cnblogs.com/z360/p/7678550.html