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

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;
}
posted @ 2021-03-30 17:48  _pwl  阅读(155)  评论(0编辑  收藏  举报
1 2 3
4