整除分块

一个有趣的问题

求一个

\sum_{i=1}^{N}\left \lfloor \frac{N}{i} \right \rfloor ,N\leq 10^{12}

1.\left \lfloor \frac{N}{i} \right \rfloor最多只有2\sqrt{N}种取值不同

2.设 \left \lfloor \frac{N}{i'} \right \rfloor\left \lfloor \frac{N}{i} \right \rfloor相等,则i'的最大值为 \left \lfloor \frac{N}{\left \lfloor \frac{N}{i} \right \rfloor} \right \rfloor

证明不证

所以 我们就可以设置两个指针L R, L初值赋值为1,每次令R=\left \lfloor \frac{N}{\left \lfloor \frac{N}{L} \right \rfloor} \right \rfloor,将(R-L+1)*\left \lfloor \frac{N}{L} \right \rfloor累加在答案中去,再令L=R+1

即可得到答案 因为\left \lfloor \frac{N}{i} \right \rfloor最多只有2\sqrt{N}种取值,所以时间复杂度为O(\sqrt{N}

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define db double
#define MAX 1000000
#define rep(i,j,k) for(int i=(int)(j);i<=(int)(k);i++) 
#define per(i,j,k) for(int i=(int)(j);i>=(int)(k);i--)
int main()
{
	//求n/i的和
	//  时间复杂度为根号N
	ll N = 100000000000;
	ll l, r;
	ll sum = 0;
	for (l = 1; l <= N; l = r + 1) {
		r = N / (N / l);
		sum += (r - l + 1)*(N / l);
	}
	cout << sum << endl;
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值