不会数论分块的小伙看过来。
由于最大能到,可以明确不同的值只有级别个,所以中的在某一个区间之内,向上取整的值都是一样的,那么我们怎么去确定右区间呢。实际上我们可以用二分来确定右区间。二分的左右边界,若当前要除的值为,那么左边界就是,右边界为,若,说明右边界大了即,否则。找了向上取整的右边界,我们就可以快速的求和了。

复杂度

时间复杂度为

代码

class Solution {
public:
    /**
     * 
     * @param n int整型 
     * @return long长整型
     */
    int Find(int n,int i)
    {
        int x=ceil(1.0*n/i);
        int l=i;
        int r=n;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(ceil(1.0*n/mid)<x)
                r=mid-1;
            else
                l=mid+1;
        }
        return r;
    }
    long long Sum(int n) {
        // write code here
        long long ans=0;
        for(int i=1,last; i<=n; i=last+1)
        {
            last=Find(n,i);
            ans+=(last-i+1)*int(ceil(1.0*n/i));
        }
        return ans;
    }
};