整除分块

学习了整除分块,感觉不是很难qwq

参考

引入

这道题:UVA11526 H(n)

就相当于求这个柿子:(oxed{sumlimits_{i=1}^{n}leftlfloordfrac{n}{i} ight floor})

很明显(O(n))是可以求的,暴力地打上这样的代码:

#include<iostream>
using namespace std;
long long H(int n){
    long long res=0;
    for(int i=1; i<=n; ++i) 
        res+=n/i;
    return res;
}//题目给的函数
int main()
{
    long long n,t;
    cin>>t;
    while(t--){
        cin>>n;
        cout<<H(n)<<endl;
    }
}

不过,提交后,惨烈的TLE了

题面要是能给你答案那这题有什么意义

所以我们需要更快的方式惹qwq

我们有(O(sqrt n))的做法——整除分块

求的是(leftlfloordfrac{n}{i} ight floor)

因为是向下取整,所以有些值是一样的

比如(n=5)时,(leftlfloordfrac{n}{3} ight floor)(leftlfloordfrac{n}{4} ight floor)(leftlfloordfrac{n}{5} ight floor)的结果一样

不难发现,这些值是像块状一样分布的(qwq)

每一个值相同的块的(i)的最大值一定是(leftlfloordfrac{n}{leftlfloordfrac{n}{i} ight floor} ight floor)

可以写出以下代码qwq(附解释):

那么时间复杂度呢?

解:(leftlfloordfrac{n}{i} ight floor)的取值最多只有(2sqrt n)种,理由如下

(1leqslant i leqslant sqrt n)时,(i)的取值有(sqrt n)种,则上述式子最多只有(sqrt n)种取值
(sqrt n leqslant i leqslant n)时,上述式子取值最多也有(sqrt n)
总共最多有(2sqrt n)种取值

由于代码枚举了(2sqrt n)次取值,复杂度便为(sqrt n)

比暴力好了许多(qwq)

习题:

1 题解
2

原文地址:https://www.cnblogs.com/RadestionAdtinium/p/13194330.html