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


京公网安备 11010502036488号