您的位置:首页 > 其它

FZU 2191 完美的数字

2016-04-17 00:28 197 查看

题目链接: 传送门

完美的数字

Time Limit: 1000MS     Memory Limit: 65536K

题目描述


Bob是个很喜欢数字的孩子,现在他正在研究一个与数字相关的题目,我们知道一个数字的完美度是 把这个数字分解成三个整数相乘AAB(0<A<=B)的方法数,例如数字80可以分解成1180,2220 ,445,所以80的完美度是3;数字5只有一种分解方法115,所以完美度是1,假设数字x的完美度为d(x),现在给定a,b(a<=b),请你帮Bob求出S,S表示的是从a到b的所有数字的流行度之和,即S=d(a)+d(a+1)+…+d(b)。



输入


输入两个整数a,b(1<=a<=b<=10^15)


输出


输出一个整数,表示从a到b的所有数字流行度之和。


输入示例


180


输出示例


107


思路


假设要求[1,80](即a=1,b=80)的数字完美度之和。 因为要拆成A * A * B的形式,我们可以令 80/(A * A), 随便取一个数A,我们看看有什么规律。 当A=3时,t = 80/(3 * 3) = 8。 即可以得到8种情况 :

3 * 3 * 1 = 9,

3 * 3 * 2 = 18,

3 * 3 * 3 = 27,

3 * 3 * 4 = 36,

3 * 3 * 5 = 45,

3 * 3 * 6 = 54,

3 * 3 * 7 = 63,

3 * 3 * 8 = 72

这些情况的值在80范围内,他们是A=3时,B的所有可能的情况。 又由于A<=B,所以排除

3 * 3 * 1 ,

3 * 3 * 2 ,

即 B=1,2 的情况。 那么剩下6种情况(t-A+1=8-3+1=6)。所以,[a,b]的流行度就是 f(b)-f(a-1)


#include <cstdio>
#include <cmath>
typedef __int64 LL;
LL a, b;
LL cal(LL k)
{
LL p = (LL)pow((double)k,1.0/3);
LL ans = 0;
for(LL i = 1; i <= p; i++)
{
ans += k/(i*i)-i+1;
}
return ans;
}
int main()
{
while(~scanf("%I64d%I64d",&a,&b))
{
LL sum = cal(b)-cal(a-1);
printf("%I64d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: