洛谷题解P1403 [AHOI2005]约数研究 Description Solution

洛谷题解P1403 [AHOI2005]约数研究
Description
Solution

给定 (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;
}