XTU1215 因子和

来源:互联网 发布:侠客风云传优化 编辑:程序博客网 时间:2024/06/05 20:20

因子和

Accepted : 32 Submit : 235Time 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 16 61 60 0

样例输出

11233

    题意很简单,求给定区间内的每个数的因子的和的和。直接暴力是不行的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
原创粉丝点击