【小技巧】除法分块

今天小Srf给大家介绍一下除法分块。

除法分块就是由于一个整数 N 除以 i (从 1 - N) 总共只有 ≈ sqrt(N) 个值 (PS : sqrt(N) 就是 根号N , 这里的值只包括除法中的商 , 和余数没有半毛钱关系)

所以,我们可以把计算 ∑N / i (1 <= i <= N) 的复杂度从 O(N) 降到 O(sqrt(N)) .

具体操作如下:

我们可以维护一个区间段 Begin 和 End , 一开始 Begin = 1.

每次计算,我们就先从 Begin 的值计算出这个区间的 End:
End = min( N , N / (N / Begin) ) (PS : 这里的 / 是指程序中的整除运算(下同) , 习惯化简的同学们注意了)

然后 , 这个区间的 ∑ N / i (Begin <= i <= End) 就是 (N / Begin) * (End - Begin + 1) (PS : * 指乘法)

下一个区间的 Begin = 当前区间的 End + 1 .

再用一个变量 tot 累加答案就可以了。

程序段(C++):

long long solve(int N){
    int L= 1,R;
    long long tot = 0LL;
    while (L <= N){
        R = N / (N / L);
        tot += (N / L) * (R - L + 1LL);
        L = R + 1;
    }
    return tot;
}
// 由于有 min() 函数,所以需要 cmath 头文件

除法分块的应用:

【洛谷】P2261 [CQOI2007]余数求和 // 此题题解可以参照 YMY666 dalao 的 Blog : http://www.cnblogs.com/YMY666/p/8149228.html

转载于:https://www.cnblogs.com/s-r-f/p/8151027.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值