Problem A Divisors
给出$m$个不同的正整数$a_i$,设数论函数 $f(k) = \sum\limits_{i = 1}^{n} [(\sum\limits_{j = 1}^{m} [a_j | i] )== k]$
其中$b|a$表示$a$是$b$的因数,对于所有$k \in [0,m]$,输出答案。
对于$100\%$的数据满足$n\leq 200 , a_i \leq 10^9$
Solution :
如果我们已知$\sum\limits_{i = 1}^{m} f(i)$,那么显然$f(0) = n - \sum\limits_{i = 1}^{m} f(i)$。
考虑到如果$j \in [1,n]$是任意一个$a_i$的因数的时候,它一定被所有$a_i$因数的集合包含。
因为除去这个集合的其他$[1,n]$的数字,必然对$f(0)$贡献。
所以,直接对于每个数暴力出它的所有因数,构出这个集合$S$。其中$|S| = 2 m\sum\limits_{i = 1}^{m} \sqrt{a_i}$
对该集合去重后暴力处理出$f(1) ... f(m)$,那么$f(0) = n - \sum\limits_{i = 1}^{m} f(i) $可以方便出解。
总时间复杂度为$O(m^2\sum\limits_{i = 1}^{m} \sqrt{a_i})$
# include <bits/stdc++.h> using namespace std; const int N=205; int n,m,a[N],ans[N]; vector<int>tmp; void work(int x) { for (int i=1;i*i<=x;i++) if (x%i==0) { tmp.push_back(i); tmp.push_back(x/i); } } int calc(int x) { int t = 0; for (int i=1;i<=m;i++) if (a[i] % x == 0) t++; return t; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int t; scanf("%d",&t); work(t); a[i] = t; } sort(tmp.begin(),tmp.end()); tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end()); for (int i=0;i<tmp.size();i++) if (tmp[i]<=n) { ans[calc(tmp[i])]++; } ans[0]=n; for (int i=1;i<=m;i++) ans[0]-=ans[i]; for (int i=0;i<=m;i++) printf("%d\n",ans[i]); return 0; }