zoukankan      html  css  js  c++  java
  • FZU-2191 完美的数字 简单数论

    题目传送门

    大致题意:

    定义(d(x))为把(x)拆分为(A*A*B(1leq Aleq B))的方案数。求(sum^{b}_{x=a} d(x))

    (1leq a leq b leq 10^{15})


    Solution

    首先,([1,n])中被(k)整除的个数有(lfloor frac{n}{k} floor)个。

    转换一下题目,就是要求满足([a,b])中满足$i^3leq x $ 且(i^2 | x)(x)的个数。

    先不管前一个条件,如果只需要满足(i^2|x)该如何实现?

    只需要枚举(i^2),并累加(lfloor frac{n}{i^2} floor)到答案上。

    但因为我们只能快速求得([1,n])中被(i^2)整除的数的个数,所以考虑用类似前缀和的东西,用([1,b])的答案减去([1,a-1])的答案。

    那么问题转化为了求([1,n])间满足条件的个数。那么就枚举(1leq i^2leq n)即可。

    但由于(x)要满足(i^3 leq x),所以累加的应该是([i^3,n])之间被(i^2)整除的数。那么累加的就改为(lfloor frac{n}{i^2} floor - lfloor frac{i^3-1}{i^2} floor)

    显然(n)要大于(i^3),那么枚举(i)的上界到(sqrt[3] n)即可。

    (10^{15})注意longlong。

    code:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll solve(ll b)
    {
        ll B=cbrt(b),ans=0;
        for(ll i=1;i<=B;i++)
            ans+=(b/(i*i)-((i*i*i-1ll)/(i*i))); 
        return ans;
    }
    int main()
    {
        ll ans=0,a,b;
        scanf("%lld%lld",&a,&b);
        printf("%lld
    ",solve(b)-solve(a-1));
        return 0;
    }
  • 相关阅读:
    平衡数问题
    重复值判断练习题
    小范围排序
    堆排序
    基数排序
    计数排序
    希尔排序
    快速排序
    Effective C++笔记:实现
    Effective C++笔记:设计与声明
  • 原文地址:https://www.cnblogs.com/moyujiang/p/13752092.html
Copyright © 2011-2022 走看看