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