学习了整除分块,感觉不是很难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)