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;
 }
div.cpp

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案