牛客小白月赛101:tb的数数问题(筛法)

宁睿  论坛元老 | 2024-9-23 20:23:38 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1084|帖子 1084|积分 3262

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目形貌

tb 给了 fc 一个包罗若干个数字的可重集合 AAA ,如果我们说一个数字 xxx 是好的当且仅当 ∀ d∣x\forall \ d | x∀ d∣x ,有 d∈Ad \in Ad∈A。

如今,fc 想知道有多少个不同的正整数是好的,请你告诉他吧。
 
d∣xd|xd∣x : 表现 ddd 为 xxx 的约数。

∀ d∣x\forall \ d | x∀ d∣x ,有 d∈Ad \in Ad∈A : xxx 的任何约数都至少在 AAA 中出现一次。
输入形貌:

  1. 第一行输入一个正整数 n(1≤n≤106)n(1 \le n \le 10^6)n(1≤n≤106) ,表示集合的大小。
  2. 第二行输入 nnn 个数,表示集合 AAA 中的元素 ai(1≤ai≤106)a_i(1 \le a_i \le 10^6)ai​(1≤ai​≤106) 。
复制代码
输出形貌:

  1. 一个非负整数,表示好的数的个数。
复制代码
示例1
输入

复制7 1 4 3 8 10 8 9
  1. 7
  2. 1 4 3 8 10 8 9
复制代码
输出

复制3
  1. 3
复制代码
备注:

  1. 样例 111 解释:
  2. 符合条件的正整数有 1,3,91,3,91,3,9 ,由于 222 不在 AAA 中,其它数又都是 222 的倍数,所以其它数均不符合条件。
复制代码
做法

用类似埃式筛法的做法,把不符合条件的数字筛掉
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1e6+10;
  4. int n,a[N],vis[N],sign,st[N],ans;
  5. unordered_map<int,int>mp;
  6. int main(){
  7.     scanf("%d",&n);
  8.     for(int i=1;i<=n;i++) {
  9.         scanf("%d",&a[i]);
  10.         vis[a[i]]++;
  11.         mp[a[i]]++;//去重
  12.         if(a[i]==1) sign=1;
  13.     }
  14.     if(!sign) {
  15.         cout<<0;
  16.         return 0;
  17.     }
  18.     for(int i=2;i<=1e6;i++){
  19.         if(!vis[i]&&!st[i]){//数组中没有这个数,且没有被去除掉
  20.             for(int j=i;j<=1e6;j+=i){//它的倍数都被去除
  21.                 vis[j]=0;
  22.                 st[j]=1;
  23.             }
  24.         }
  25.     }
  26.    
  27.     for(auto x:mp) {
  28.         if(vis[x.first]) ans++;
  29.     }
  30.     cout<<ans;
  31. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宁睿

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表