divisors 数学

给定\(m\)个不同的正整数\(a_1, a_2,\cdots, a_m\),请对\(0\)到\(m\)每一个\(k\)计算,在区间\([1, n]\)里有多少正整数是\(a\)中恰好\(k\)个数的约数。

极度考验语文能力的题面。

套路一般分解质因数,但是我们发现分解质因数之后统计会很麻烦,又发现\(m\),\(a_i\)的所有约数个数又很小,所以我们索性将\(m\)个数分别都预处理出所有可能的约数分解形式丢进栈,之后直接sort栈,线性统计答案即可。

另外,我们发现\([1,n]\)每一个数都只能被计算一次,所以在区间\([1, n]\)里有多少正整数是\(a\)中恰好0个数的约数的个数即为\(n-sum\)

#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <algorithm>
int s[10000010],s_top;
int res[202];
int n,m,a[202];
int main(){
scanf("%d %d", &n, &m);
for(int i=1;i<=m;++i) scanf("%d", &a[i]);
for(int i=1;i<=m;++i){
int tmp=(int)sqrt(a[i]);
for(int j=1;j<=tmp;++j)
if(a[i]%j==0) s[++s_top]=j,s[++s_top]=a[i]/j;
if(tmp*tmp==a[i]) --s_top;
}
std::sort(s+1, s+1+s_top);
int cur_cnt=1;
for(int i=2;i<=s_top;++i){
if(s[i]>n) break;
if(s[i-1]==s[i])
++cur_cnt;
else{
++res[cur_cnt];
cur_cnt=1;
}
}
++res[cur_cnt];
int sum=0;
for(int i=1;i<=m;++i) sum+=res[i];
printf("%d\n", n-sum);
for(int i=1;i<=m;++i) printf("%d\n", res[i]);
return 0;
}

最新文章

  1. MVC 教程汇总
  2. iOS进阶篇索引,标记和自定义的table
  3. JavaScript思维导图—Window对象
  4. 解决visualsvn监听ip 错误的问题
  5. 阿里云开放服务oss的api
  6. RegExp.exec
  7. MySQL与NoSQL——SQL与NoSQL的融合
  8. shell小程序
  9. 在Qt中用QAxObject来操作Excel
  10. http协言和web本质
  11. MyEclipse下Struts2配置使用和Ajax、JSON的配合
  12. integer与int区别以及integer.values()方法详解
  13. JavaScript练习网站收集
  14. Scala之String
  15. .net core 并发下的线程安全问题
  16. Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) B. Weakened Common Divis
  17. CentOS 7 Squid代理服务器正向代理-传统代理
  18. python地理处理包——geopy使用之地理编码与反地理编码
  19. Windows核心编程:第2章 字符和字符串处理
  20. C#编程(六十四)----------并行扩展

热门文章

  1. Linux or Mac 重启网络
  2. easyExcel用于导入导出
  3. Python之算法模型-5.1
  4. 腾讯域名使用百度CDN加速配置
  5. mac os安装mtr
  6. 【转载】C#将字符串中字母全部转换为大写或者小写
  7. 【转载】 C#使用Union方法求两个List集合的并集数据
  8. linux 下调用wps 注意
  9. Java 之 InputStreamReader 类
  10. angular2-cli 环境搭建