2020-4-20训练赛

问题 A: 结队

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

众所周知,小X是一个风流倜傥、有极高人格魅力的奆老。
奆老总喜欢挑战高难度的事情,幻想着横穿和自己一样大名鼎鼎的亚马逊雨林。
这个幻想了7083年的事情终要变为现实,小X高兴得连灌两盆洗脚水。
“啊……真香……该死的甜美…………”

古代著名学者度娘在《百度百科》一书中说到:
亚马逊热带雨林(AmazonRainForest)位于南美洲的亚马逊平原,占地550万平方公里。雨林横越了9个国家:巴西(占森林60%面积)、哥伦比亚、秘鲁、委内瑞拉、厄瓜多尔、玻利维亚、圭亚那、苏里南以及法国(法属圭亚那),占据了世界雨林面积的一半,占全球森林面积的20%,是全球最大及物种最多的热带雨林。

小X万年一遇地被吓尿了。他感到面临着生命危险,需要小弟来保护,而自己的小弟实在是太少了,小X灵机一动,想到JSOI的夏令营中有很多dalao。小X照照镜子,被自己的人格魅力深深折服,信心满满。
[9102年8月8日,江苏省常州高级中学]
刚下车,小X身旁就围了一大群猛男。
“小X最帅!”
没有想到的是,小X居然被秀了。省中的dalao早已准备在这一天组成帮派。

省中的dalao从1~n进行编号。小X口味独特,只想让[a,b]区间内的dalao做自己的小弟。
dalao遵循以下规则组成帮派:
最初每个人都自成帮派。组帮派时,对于序号为m,n两个属于不同帮派的dalao,如果m,n有大于等于p的公共质因数,那么m,n所在的帮派就会合并为同一帮派。合并过后的帮派会继续合并,直至没有可以合并的帮派。
小X作为一个奆老,秉承着装弱的传统。他需要你告诉他,一共会有多少不同的帮派。

输入

一行,三个正整数A,B,P。(保证A≤B)

输出

一个正整数,表示最终的帮派个数。

样例输入 Copy

10 20 3

样例输出 Copy

7

提示

样例解释
对于[10,20]中的dalao,可分成如下帮派:
{10,20,12,15,18}  {11}  {13}  {14}  {16}  {17}  {19}
【数据范围】
对于30%的数据,保证有0≤A≤B≤100,P≤100
对于60%的数据,保证有0≤A≤B≤3000,P≤3000
对于100%的数据,保证有0≤A≤B≤50000,P≤50000

 

开始用了很多奇奇怪怪的方法。。。。这个其实可以打表法~~~

#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
const int N=50005;
 int a,b,p;
int m[N],fa[N],vis[N],mod[N],cnt=0,ans=0;
int findfa(int i)
{
    if(fa[i]!=i) return findfa(fa[i]);
    return fa[i];
}
void init()
{

    for(int i=2;i<=N;i++)
    {
         int f=0;
        for(int j=2;j*j<=i;j++)
        {
            if(i%j==0)
            {
                f=1;
                break;
            }
        }
        if(f==0) mod[++cnt]=i;

    }
}
int main()
{

   scanf("%d%d%d",&a,&b,&p);
   init();
   for(int i=a;i<=b;i++){fa[i]=i;}
   //for(int i=1;i<=cnt;i++)    printf("%d ",mod[i]);
   for(int i=1;i<=cnt;i++)
   {
       if(mod[i]<p) continue;
       if(mod[i]>b) break;
       int f=0;
       for(int j=1;;j++)
       {
           if(j*mod[i]>b) break;
           if(j*mod[i]>=a)
           {
               if(vis[j*mod[i]]==1)
                 f=1;
                 vis[j*mod[i]]=1;
           }
       }
       if(f==0) ans++;
//       for(int i=a;i<=b;i++)
//        printf("%d ",vis[i]);
//       printf(" * * %d %d\n",ans,mod[i]);
 }
   for(int i=a;i<=b;i++)
    if(vis[i]==0) ans++;
   printf("%d",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值