XTU1215 因子和

9 篇文章 0 订阅

因子和

Accepted : 32 Submit : 235
Time Limit : 4000 MS Memory Limit : 65536 KB 

题目描述

如果b能整除a,我们称b为a的因子。现在假设n的所有因子和为f(n);
给你两个整数a,b,(0 ≤ a ≤ b ≤ 5000000);
请你求出所有满足a ≤ i ≤ b的f(i)的和;
例如a=1,b=6,那么你就需要计算f(1)+f(2)+f(3)+f(4)+f(5)+f(6)。
我们规定f(0)=0;

输入

不超过2000个样例,每个样例占一行,为两个整数a,b;a=b=0时表示输入结束。

输出

每个样例输出一个整数,占一行。

样例输入
1 1
6 6
1 6
0 0

样例输出
1
12
33


    题意很简单,求给定区间内的每个数的因子的和的和。直接暴力是不行的N*sqrt(N);N有5000000一定超时的,那么我们来看看怎么优化这种暴力的思想。在枚举2~sqrt(N)的时候,只有被当前数整除的才可以算进来,不能整除的数是废的,都没有必要试,那么我们可以不去这样盲目的尝试,而是去枚举约数,由于N<=5000000,所以约数有sqrt(5000000)个,用两两组合的方式来枚举约数,就可以使得每一个枚举都是有效的,而枚举的复杂度是n^2,这里n = sqrt(N) ,最大也就是5000000了,预处理一下就OK了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iostream>
const int N = 5000010;
using namespace std;
typedef long long ll;
ll sum[N];
int main()
{
	int n;
	for(int i = 2;i < N;i ++)
		sum[i] = i+1 ;//这里为了处理质数,
	sum[1] = 1;//由于全局变量会默认初始化为0,所以sum[0]已经是0了
	for(int i = 2;i*i < N;i ++)
	{
		for(int j = i + 1;i*j < N;j ++)
			sum[i*j] += i + j;
		sum[i*i] += i;
	}


	for(int i = 1;i <= 5000000 ;i ++)
		sum[i] += sum[i-1];//获得前缀和,这样sum[i]就是0~i的数的因子和了
	int a,b;
	while(~scanf("%d%d",&a,&b))
	{
		if(a == 0&&b == 0)break;
		if(a > b)a ^= b ^= a ^= b;//这里可能a会大于b,所以判一下
		
		cout<<(sum[b] - sum[a?a-1:a])<<endl;
	}
	return 0;	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值