ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

整除分块 学习笔记

2022-04-25 20:33:55  阅读:203  来源: 互联网

标签:lfloor le frac 分块 rfloor 笔记 sqrt 整除 operatorname


板子题

板子题-UVA11526
题目大意:
给定一个 \(n\),求 \(\sum\limits_{i-1}^{n}\lfloor \frac{n}{i} \rfloor\)。其中 \(n\) 为 \(32\) 位无符号整数。

题目解析

显然如果暴力求解肯定是不可行的,显然会 TLE,所以我们需要找一种复杂度更优的算法。
我们可以先令 \(n=10\),观察一下函数 \(\operatorname{f}(x)=\lfloor\frac{n}{x}\rfloor\) 的图像:

观察可以发现,不难发现:
当 \(x=1\) 的时候,\(\operatorname{f}(x)=10\)。
当 \(x=2\) 的时候,\(\operatorname{f}(x)=5\)。
当 \(x=3\) 的时候,\(\operatorname{f}(x)=3\)。
当 \(x=4,5\) 的时候,\(\operatorname{f}(x)=2\)。
当 \(x=6,7,8,9,10\) 的时候,\(\operatorname{f}(x)=1\)。
我们是否能够预处理出每个使 \(\operatorname{f}(x)\) 相同的区间来更快地计算答案呢?
不难发现以下结论:

\[\forall n\in\mathbb{N}_+, \left| \{ \lfloor\frac{n}{i}\rfloor \mid i\in\mathbb{N}_+,i\le n \} \right| \le 2 \lfloor\sqrt{n}\rfloor \]

证明:
当 \(i\le \lfloor\sqrt{n}\rfloor\) 时,\(\lfloor\frac{n}{i}\rfloor\) 最多 \(\lfloor\sqrt{n}\rfloor\) 个数字。
当 \(\lfloor\sqrt{n}\rfloor<i\le n\) 时,\(1\le\lfloor\frac{n}{i}\rfloor\le\lfloor\sqrt{n}\rfloor\),最多有 \(\lfloor\sqrt{n}\rfloor\) 个数字。
因此最多只有 \(2\sqrt{n}\) 个数字。

整除分块结论

对于一个数字 \(n\),如果 \(\lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{j}\rfloor\) 成立,那么满足 \(i<j\le n\) 最大的 \(j\) 为 \(\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor\)
根据前面的结论,这种做法的复杂度为 \(\Theta\left(\sqrt{n}\right)\)。
代码:

#include<cstdio>
#define ll long long
using namespace std;
ll n,ans;
void work(){
	scanf("%lld",&n); ans=0; ll l=1,r;
	while(l<=n){ r=n/(n/l); ans+=(r-l+1)*(n/l); l=r+1; }
	printf("%lld",ans),putchar('\n'); return;
}
int main(){
	int T; scanf("%d",&T); while(T--) work(); return 0;
}

引申

显然在一般的求值题目中的式子不会这么简单,一般都形如

\[\sum_{i=1}^{n}\operatorname{f}(i)\lfloor\frac{n}{i}\rfloor \]

此时预处理出 \(\operatorname{f}(x)\) 的前缀和 \(\operatorname{g}(x)\) 就可以在 \(\Theta\left(\sqrt{n}\right)\) 求出这个式子的值了。
代码大致如下:

l=1,sum=0;
while(l<=n){
  r=n/(n/l);
  ans+=(g(r)-g(l-1))*(n/l);
  l=r+1;
}

多维数论分块

如果求值的函数中含有 \(\lfloor\frac{a_1}{i}\rfloor+\lfloor\frac{a_2}{i}\rfloor+\dots+\lfloor\frac{a_n}{i}\rfloor\),
那么我们只需要将前面的结论的 \(\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor\) 改为 \(\min \limits^{n}_{j=1} \lfloor\frac{a_j}{\lfloor\frac{a_j}{i}\rfloor}\rfloor\) 即可。
(当然 \(n=2,n=3\) 的情况比较常见)

标签:lfloor,le,frac,分块,rfloor,笔记,sqrt,整除,operatorname
来源: https://www.cnblogs.com/jiangtaizhe001/p/16191786.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有