zoukankan      html  css  js  c++  java
  • Set 集合

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

    对于两个个数,如果他们含有大于p的质因数,那么一定会被合并

    我们发现集合可以按质因数分成很多,那么含有该因数的数会在这个集合

    如果一个数同时含有两个因数,那么这两个区间会合并

    于是就可以用并查集

    可以枚举A~B,枚举质因数

    假设一个数i有p1,p2,p3为质因数

    把一个质因数的区间与前一个合并

    这只有80分

    如果枚举质因数,再枚举倍数,看一个倍数是否被其他倍数覆盖,是则合并

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 int A,B,P,tot,pri[100001],set[10001],cnt,st,flag,pre,num[100001];
     8 bool vis[100001];
     9 int find(int x)
    10 {
    11   if (set[x]!=x) set[x]=find(set[x]);
    12   return set[x];
    13 }
    14 int main()
    15 {int i,j;
    16   cin>>A>>B>>P;
    17   for (i=2;i<=B;i++)
    18     {
    19       if (vis[i]==0)
    20     {
    21       tot++;
    22       pri[tot]=i;
    23     }
    24       for (j=1;j<=tot;j++)
    25     {
    26       if (pri[j]*i>B) break;
    27       vis[i*pri[j]]=1;
    28       if (i%pri[j]==0) break;
    29     }
    30     }
    31   memset(vis,0,sizeof(vis));
    32   for (i=1;i<=tot;i++)
    33     if (pri[i]>=P) break;
    34   st=i;
    35   for (i=st;i<=tot;i++)
    36     set[i]=i;
    37   for (i=st;i<=tot;i++)
    38     {
    39       int a=((A-1)/pri[i]+1);
    40       int b=(B/pri[i]);
    41     if (a<=b) vis[i]=1;
    42       for (j=a;j<=b;j++)
    43     {
    44       if (num[j*pri[i]]==0) num[j*pri[i]]=i;
    45       else 
    46         {
    47           int p=find(i);
    48           int q=find(num[j*pri[i]]);
    49           if (p!=q)
    50         {
    51           set[p]=q;
    52         }
    53         }
    54     }
    55     }
    56   for (i=A;i<=B;i++)
    57     if (num[i]==0) cnt++;
    58   for (i=st;i<=tot;i++)
    59     if (set[i]==i&&vis[i]==1) cnt++;
    60   cout<<cnt;
    61 }
  • 相关阅读:
    QT开发之旅一DS7400主机调试工具
    读《程序员,你伤不起》杂感(附带分享两个项目源码)
    这些年过上幸福生活的程序员(中篇)
    这些年过上幸福生活的程序员(上篇)
    如果第三方数据表与系统数据库里的表名格式不一致的解决方案
    数据库设计原则
    MYSQL密码设置
    关于phpmyadmin #1045无法登陆服务器的问题
    TP快捷函数
    跨控制器调用
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7757917.html
Copyright © 2011-2022 走看看