Description
给定 (n) ,规定 (f(n)) 表示 (n) 的约数个数,求 (sum_{i=1}^n f(i))
Solution
20pts
数据范围小,直接求即可。
Code
#include<iostream>
#include<cstdio>
using namespace std;
inline void read(int &x){
int f=1;
char ch=getchar();
x=0;
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
x*=f;
}
int cnt[5001],sum[5001];
signed main(){
for(int i=1;i<=5000;i++){
for(int j=1;j<=i;j++){
if(i%j==0) cnt[i]++;
}
}
for(int i=1;i<=5000;i++){
for(int j=1;j<=i;j++){
sum[i]+=cnt[j];
}
}
int n;
read(n);
printf("%d",sum[n]);
return 0;
}
100pts
考虑如何优化时间复杂度。可以观察到,每次直接求一个数其约数个数十分浪费时间,不妨转换思路。由「寻找 (n) 的约数」转换为「若 (x) ((x in [1,n])) 作为因数,其在 ([1,n]) 中作为了多少个数的因数?(出现了多少次?)」
不难发现,(1) 在 ([1,n]) 中有 (n) 个倍数,(2) 在 ([1,n]) 中有 ([frac{n}{2}]) 个倍数,(cdots) ,(n) 在 ([1,n]) 中有 (1) 个倍数。
则求 (sum_{i=1}^n f(i)) ,只需求 (sum_{i=1}^{n}[frac{n}{i}]) 即可。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int Maxn=1010;
inline void read(int &x){
int f=1;
char ch=getchar();
x=0;
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
x*=f;
}
signed main(){
int sum=0;
int n;
read(n);
for(int i=1;i<=n;i++) sum+=n/i;
printf("%d",sum);
return 0;
}