1 条题解
-
0
【题目大意】给定 ,m,K。定义 为满足 和 的最小公倍数是 的约数的数对 的个数,求
【考纲知识点】数学,调和级数
【解题思路】 题目求,因此不能直接通过 和去更新 。而由数据范围,先猜测预处理,正着想很难想,我们可以逆向思考; 假设,有一个数 ,存在一对 满足上述条件,即 和 的最小公倍数 的约数。那么容易得到 ,,都是 的约数。 那么,反过来,是不是就有 中是的约数的个数中是的约数的个数; 因为由唯一分解定理易得,一个数的两个约数的最小公倍数一定还是这个数的约数。因此满足条件的 一定在 的约数当中,不满足条件的 一定不在 的约数当中。排列组合一下,即可得到答案。 现在问题变成了怎么预处理一个数的约数个数。 这个简单,类似质数筛的方法,枚举 ,将符合的 标记一下即可
【参考程序】
#include<bits/stdc++.h> using namespace std; inline long long read(){ long long x=0,f=1; char c=getchar(); while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x*f; } const int K=1e6+10; int sumn[K],summ[K]; int main(){ int n=read(),m=read(),k=read(); for(int i=1;i<=n;i++) for(int j=i;j<=K;j+=i) sumn[j]++; for(int i=1;i<=m;i++) for(int j=i;j<=K;j+=i) summ[j]++; long long ans=0; for(int i=1;i<=k;i++) ans=ans+(long long)i*sumn[i]*summ[i];//※结论得到 cout<<ans; return 0; }
- 1
信息
- ID
- 597
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 9
- 标签
- 递交数
- 9
- 已通过
- 5
- 上传者