FZU 2191 完美的数字

Problem 2191 完美的数字

Accept: 50    Submit: 146
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

Bob是个很喜欢数字的孩子,现在他正在研究一个与数字相关的题目,我们知道一个数字的完美度是 把这个数字分解成三个整数相乘A*A*B(0<A<=B)的方法数,例如数字80可以分解成1*1*80,2*2*20 ,4*4*5,所以80的完美度是3;数字5只有一种分解方法1*1*5,所以完美度是1,假设数字x的完美度为d(x),现在给定a,b(a<=b),请你帮Bob求出

S,S表示的是从a到b的所有数字的流行度之和,即S=d(a)+d(a+1)+…+d(b)。

 Input

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

 Output

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

 Sample Input

1 80

 Sample Output

107

 Source

福州大学第十二届程序设计竞赛


分析题意可以知道,因为0<A<=B,而且要求NUM=A*A*B,所以A最大就是三次根号NUM,也就是说,瞬间将数量级下降到10^5,别急,下面的优化更吊,我们假设数据为a,b,那么对于一个确定的A,它所能表示的数最小是A*A*A,最大就是A*A*(b/(A*A)),注意这里的除法是整数的除法,也就是不带小数的,所以这个数是小于等于b的,于是,我们用NUM/(A*A)-A+1就表示从所有小于b且能够拆成A*A*B形式的数字,那么只要让A从1到三次根下b遍历,就可以求出1-b所有数字的完美度之和,注意是1-b而不是a-b,所以我们还需要算出1-(a-1)的完美度之和,算法一样,用之前的结果减去就可以了,这样说很抽象,我们举个具体的例子:

求a=80,b=80的完美度之和,实际上就是求80的完美度

1.三次根下80等于4,所以A可以从1枚举到4

2.A=1时,可以从1*1*1到1*1*80,所以总共80个完美度

3.A=2时,可以从2*2*2到2*2*20,所以总共19个完美度

4.A=3时,可以从3*3*3到3*3*8,总共6个完美度

5.A=4时,可以从4*4*4到4*4*5,总共2个完美度

所以,从1到80中所有的数字的完美度之和为107

然后要计算从1到79所有的完美度之和,A仍然是从1枚举到4

1.A=1时,可以从1*1*1到1*1*79,总共79个完美度

2.A=2时,可以从2*2*2到2*2*19,总共,18个完美度

3.A=3时,可以从3*3*3到3*3*8,总共6个完美度

4.A=4时,可以从4*4*4到4*4*4,总共1个完美度

所以从1到79总共104个完美度

107-104=3,所以,80的完美度是3

#include <iostream>
#include <cmath>
#include <stdio.h>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <iomanip>
#include <algorithm>
#include <memory.h>
using namespace std;
long long Count;
int main()
{
    long long i,j;
    long long mul;
    long long a,b;
    long long up1,up2;
    long long s,e;
    while(cin>>a>>b)
    {
        Count=0;
        up1=pow(a-1,0.33333333333333);
        up2=pow(b,0.33333333333333);
        for(i=1;i<=up2;i++)
        {
            s=i;
            e=b/(i*i);
           // cout<<s<<' '<<e<<endl;
            Count+=e-s+1;
        }
        for(i=1;i<=up1;i++)
        {
            s=i;
            e=(a-1)/(i*i);
            Count-=e-s+1;
        }
        cout<<Count<<endl;
    }
    return 0;
}








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值