首页 > 编程语言 >算法学习笔记(数学):数论分块 + 容斥原理 + 莫比乌斯函数

算法学习笔记(数学):数论分块 + 容斥原理 + 莫比乌斯函数

时间:2022-10-06 17:33:18浏览次数:83  
标签:lfloor right frac 分块 int 容斥 rfloor 莫比 left

算法学习笔记(数学):数论分块 + 容斥原理 + 莫比乌斯函数

这篇文章主要是要讲一道题目链接在这里)
以及梳理一下数论分块,莫比乌斯函数,容斥原理这些知识。
先介绍下知识点吧qwq

数论分块

想必大家一定学过数据结构中的分块操作吧,通过\(sqrt(n)\)的区间分块去提高暴力的效率,其实数列分块在本质上与其是有异曲同工之妙的,大家可以先来想想这个问题:

\[\sum_{i = 1}^{n}\left \lfloor \frac{n}{i}\right \rfloor = ? \]

对于这个问题,我们可以手动去模拟一下,比方说取\(n=9\),遍历一遍\(i\)的取值,会发现\(\left \lfloor \frac{n}{i}\right \rfloor\)的值其实是很少的,所以我们也可以像分块一样去帮他们分成几个区间去操作处理。那么怎么分呢,我们可以定义这个式子成立\(\left \lfloor \frac{n}{x}\right \rfloor = \left \lfloor \frac{n}{g(x)}\right \rfloor\),然后令\(g(x)\)为当前等式成立的情况下,\(x\)最大的取值。
先讲结论:\(g(x) = \left \lfloor \frac{n}{\left \lfloor \frac{n}{x}\right \rfloor}\right \rfloor\)
证明:令\(k = \left \lfloor \frac{n}{x}\right \rfloor\),则\(\left \lfloor\frac{n}{k} \right \rfloor >= \left \lfloor \frac{n}{\left \lfloor \frac{n}{x}\right \rfloor}\right \rfloor >= \left \lfloor x\right \rfloor = x\),所以我们就知道\(x\)最大的时候的取值了。
再证明 \(\left \lfloor\frac{n}{\left \lfloor \frac{n}{x}\right \rfloor} \right \rfloor = \left \lfloor \frac{n}{x}\right \rfloor\)
贴一下y总的证明过程(思路还是比较简单的,证明一个大于等于和一个小于等于同时成立,所以等号成立)
image
复杂度:
我们可以这么考虑复杂度,对于\(\frac{n}{i}\),当\(i <= sqrt(n)\)时,从\((1,sqrt(n))\)是只最多只有\(sqrt(n)\)个值的,因为最多的情况就是每次除都会有新的值出现。同理,大于\(sqrt(n)\)时\(n / i <= sqrt(n)\)所以最多也只有根号种取值。
所以最多有\(2*sqrt(n)\)段,复杂度\(O(sqrt(n))\)。
然后我们就可以像数列分块一样,在\(O(sqrt(n))\)的复杂度去计算前面的式子啦。

莫比乌斯函数 + 容斥原理

这两个知识放在一起讲是因为其关联性还是比较大的。
比方说这个问题是求\(gcd(x,y) = 1,(x <= a,y <= b)\)的对数是,我们很自然的可以想到容斥原理,要求的对数就等于总对数减去不合理对数,所以我们可以列出这样的一条公式:\(ans =a*b - a/2*b/2 -a/3 *b/3-a/5*b/5....+a/6*b/6.....\)
标准的容斥原理公式啦!
那么莫比乌斯函数是干啥的呢,定义如下:

\[\mu (x)=\left\{\begin{matrix} & 0 &\exists \alpha >1 \\ & (-1)^{k} & k为质因数分解项数 \\ & 1 & x=1 \\ \end{matrix}\right.\]

那么我们上面那条标准的式子是不是就可以进一步化简了?
化简式子如下:

\[\sum_{i=1}^{min(a,b)}\left \lfloor \frac{a}{i}\right \rfloor*\left \lfloor \frac{b}{i}\right \rfloor*\mu(i) \]

然后我们就可以发现,可以用数论分块来加速这条式子哩。于是我们就可以切掉这道题了(链接在文章开头)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long long ll;
#define int long long
#define endl '\n' 
typedef pair<int, int> PII;
const int N = 5e4 + 20;
const int Inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
int primes[N];
int mobius[N];
bool st[N];
int cnt;
int sum[N];
void init(int n) {
	mobius[1] = 1;
	for (int i = 2;i <= n;i ++) {
		if(!st[i]){
			primes[cnt++] = i;
			mobius[i] = -1; 
		}
		for (int j = 0;primes[j] * i <= n;j ++) {
			st[primes[j] * i] = true;
			if(i % primes[j] == 0) {
				mobius[i * primes[j]] = 0;
				break;
			}
			mobius[i * primes[j]] = mobius[i] * -1;
		}
	}
	for (int i = 1;i <= n;i ++) sum[i] = sum[i - 1] + mobius[i];
}

void solve(){
	int a,b,d;
	cin >> a >> b >> d;
	a = a / d;
	b = b / d;
	int n = min(a,b);
	int ans = 0;
	for (int l = 1,r;l <= n;l = r + 1) {
		r = min(n , min(a / (a/ l),b / (b / l))); // 不能超过n
		ans = ans + (sum[r] - sum[l - 1]) * (a / l) * (b / l); // 这里 a / l 和 b / l 是相同的,所以式子提取出来,就可以用莫比乌斯函数的前缀和了
	}
	cout << ans << endl;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int t;
	init(N);
	cin >> t;
	while (t--) solve();
	// solve(); 
    return 0;
} 
 

qwq希望这样的整理能有点用(latex公式确实很难打)
image

标签:lfloor,right,frac,分块,int,容斥,rfloor,莫比,left
From: https://www.cnblogs.com/zwh-zzz/p/16758067.html

相关文章

  • LG8569 JRKSJ R6 第七学区(分块)
    LG8569JRKSJR6第七学区\(N\)序列\(a\),求所有子区间按位或和的和。\(N\le5\times10^7\)。CODE每\(r=8\)位一段。维护当前每个位最后一个出现位置和贡献和......
  • 【Ynoi2009】 rla1rmdq 题解 (离线分块 + 线性空复处理)
    洛谷传送门分块。Solution看到是区修区查,还有时限,不难想到是分块,根号复杂度。然后看到空间复杂度,需要离线下来转为线性复杂度。考虑如何分块。观察操作性质,发现节点......
  • 数列分块入门
    数列分块入门算是入门了吧写在前面本人十分之Naive所以写的不好还请见谅。前置知识暴力线段树线段树貌似也不太需要,但本文建立在你已经会线段树的基础上。但真......
  • 【luogu P6779】rla1rmdq(分块)(树链剖分)
    rla1rmdq题目链接:luoguP6779题目大意给你一个n个点的有根树,根给出,和一个值域在1~n的数组。然后m次操作,每次对于一个数组的区间l~r,把它们的值都变成格子树上父......
  • luogu P5518 幽灵乐团 / 莫比乌斯反演基础练习题
    重新学习了一下莫比乌斯反演,再来写一次这道题。Part1\[\prod_{i=1}^A\prod_{j=1}^B\prod_{k=1}^C\dfrac{\text{lcm}(i,j)}{\gcd(i,k)}\]\[=\prod_{i=1}^A\prod_{j=1}^B......
  • 多任务分块下载器,支持断点续传
    多任务分块下载器MultiTaskDownloaderusingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingSystem.Net;usingSystem.Threadi......
  • AGC038C LCMs 详解(莫比乌斯反演好题)
    ProblemAGC038C给定一个长为\(n\)的序列\(A_1,A_2,\cdots,A_n\),求\(\sum_{i=1}^{n}{\sum_{j=i+1}^{n}{lcm(A_i,A_j)}}\bmod998244353\)\(n\leq2\times10^5,A_i......
  • 数列分块入门
    数列分块入门写在前面写得好的暴力叫分块,写得烂的分块叫暴力警钟敲烂修改时要先将原数组复制一份,否则无法应对边角块的修改。一定要特判$l$和$r$属于同一......
  • 容斥与反演技巧(一)
    二项式反演我们直接上式子好了一般有两种形式,第一种是\[f(n)=\sum_{i=0}^n\binom{n}{i}g(i)\iffg(n)=\sum_{i=0}^n(-1)^{n-i}\binom{n}{i}f(i)\]第二种是\[f(n)=\sum......
  • 容斥
    NC15079 大水题模板题#include<bits/stdc++.h>#defineLLlonglongusingnamespacestd;LLa[5]={0,2,5,11,13};intmain(){LLn;while(scanf("%lld"......