因子和 | ||
Accepted : 36 | Submit : 263 | |
Time Limit : 4000 MS | Memory Limit : 65536 KB |
题目描述如果b能整除a,我们称b为a的因子。现在假设n的所有因子和为f(n); 输入不超过2000个样例,每个样例占一行,为两个整数a,b;a=b=0时表示输入结束。 输出每个样例输出一个整数,占一行。 样例输入1 1 6 6 1 6 0 0 样例输出1 12 33 |
求n的因数和,由任意一个正整数可以由素数相乘得到,n = p1^x1 * p2^x2 * p3^x3.......;
得到因数和为 ans = (p1^(x1+1)-1) / ( p1 - 1 ) * (p2^(x2+1)-1) / (p2-1) * (p3^(x3+1)-1) / (p3-1)........ 可推导出说有因数和
#include <stdio.h>
#include <string.h>
int a[5000001] ;
int b[5000001] ;
int check[5000001] ;
int tot = 0 ;
void f()
{
memset(check,0,sizeof(check));
int i , j ;
for(i = 2 ; i <= 5000000 ; i++)
{
if( !check[i] )
a[tot++] = i ;
for(j = 0 ; j < tot ; j++)
{
if( i*a[j] > 5000000 )
break;
check[i*a[j]] = 1 ;
if( i % a[j] == 0 )
break;
}
}
}
__int64 F(int a,int b)
{
int i , j ;
__int64 num = 1 ;
for(i = 0 ; i < b ; i++)
num *= a ;
return num ;
}
__int64 ans[5000001] ;
int main()
{
f() ;
int i , j , k , n ;
for(i = 1 ; i <= 5000000 ; i++)
ans[i] = 1 ;
ans[0] = 0 ;
for(i = 2 ; i <= 5000000 ; i++)
{
if(i == 1000018)
k = i ;
k = i ;
n = 0 ;
b[n] = 0 ;
if(check[i] == 0)
{
ans[i] = i+1 ;
continue ;
}
while(k != 1)
{
if(check[k] == 0 && k != a[n])
break;
if(k % a[n] == 0)
{
k = k / a[n] ;
b[n]++ ;
}
else
{
n++ ;
b[n] = 0 ;
}
}
if(k != 1)
{
ans[i] = k ;
ans[i] = (ans[i]*ans[i]-1)/(ans[i]-1);
}
for(j = 0 ; j <= n ; j++)
{
if(b[j] != 0){
__int64 kk = F(a[j],b[j]+1) - 1 ;
ans[i] *= ( kk / (a[j]-1) );
}
}
}
for(i = 1 ; i <= 5000000 ; i++)
ans[i] += ans[i-1];
int l , r ;
printf("%I64d\n", ans[5000000]);
while(scanf("%d %d", &l, &r)!=EOF)
{
if(l == 0 && r == 0)
break;
if(l == 0)
printf("%I64d\n", ans[r]);
else
printf("%I64d\n", ans[r] - ans[l-1]);
}
return 0;
}