洛谷——P1621 集合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷——P1621 集合相关的知识,希望对你有一定的参考价值。

P1621 集合

题目描述

现在给你一些连续的整数,它们是从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}。

 

欧拉筛+并查集

#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;
}

 

以上是关于洛谷——P1621 集合的主要内容,如果未能解决你的问题,请参考以下文章

P1621 集合

代码片段 - Golang 实现集合操作

laravel特殊功能代码片段集合

金蝶handler中 collection 代码片段理解

Alfred常见使用

洛谷 P2415 集合求和 题解