数论基础

数论基础

余数

取模运算

取模和求余运算博客

整除分块

参考博客 然而我认为这篇的时间复杂度分析得不太对。

求 $\sum_{i=1}^{n} \lfloor \frac{n}{i} \rfloor $ 这种东西以及其他复杂很多的东西,可以 \(O(\sqrt{n})\) 求解。

最简单地,求 $\sum_{i=1}^{n} \lfloor \frac{n}{i} \rfloor $。

时间复杂度证明

注意到 \(\lfloor \frac{n}{i} \rfloor\) 的取值不超过 \(2\sqrt{n}\) 种。证明如下:

  • \(i\le \sqrt{n}\),因为 \(i\) 只有 \(\sqrt{n}\) 种,所以 \(\lfloor \frac{n}{i} \rfloor\) 的取值也只有 \(\sqrt{n}\) 种。
  • \(i> \sqrt{n}\),此时 \(\lfloor \frac{n}{i} \rfloor < \sqrt{n}\),显然取值不超过 \(\sqrt{n}\)

因此总时间复杂度为 \(O(\sqrt{n})\)

大体思路和代码

枚举 \(l\),设 \(v=\lfloor \frac{n}{l} \rfloor\),我们要找 \(v=\lfloor \frac{n}{r} \rfloor\) 的最大的 \(r\)

\[v=\lfloor \frac{n}{r} \rfloor\\ v\le \frac{n}{r}\\ r\le \frac{n}{v}\]

因此在这个例子中,\(r\)\(\frac{n}{v}\),下一块的 \(l\) 就取 \(r+1\)

for(int l=1,r=1,v=n/l;l<=n;l=r+1,v=n/l){
		r=n/v;
		ans+=v*(r-l+1);
	}

经验

P1403 [AHOI2005] 约数研究 一道小黄题,和例子一模一样,其实它的数据范围可以不用整除分块的。

P2424 约数和 很板子。

P2261 [CQOI2007] 余数求和\(k\bmod i\) 转化成 \(k-\lfloor \frac{k}{i} \rfloor i\),然后看起来非常板子。但是由于 \(i\le n\) 而本题求 \(\lfloor \frac{k}{i} \rfloor\)\(n,k\) 可能不等,需要注意边界细节。

GZOI2024 Day2 T2【乒乓球】 很复杂的整除分块。

约数

\(a|b\) 表示 \(a\) 能整除 \(b\),即 \(a\)\(b\) 的因子。

约数个数大约 \(O(n^\frac{1}{3})\) 级别。

最大公约数

——辗转相除法求 gcd

欧几里得算法: \(\gcd(a,b)=\gcd(b,a\bmod b)\)

时间复杂度 \(O(\log n)\)(我不会证明 qwq)。

Code

一行搞定我不是故意压行的

int gcd(int a,int b){return b?gcd(b,a%b):a;}

O(1) 求 gcd

参考 O(1)gcd 学习笔记

\(T=\lfloor\sqrt{V}\rfloor\)

对于一个数 \(1\le x\le V\),一定可以拆分成三个数 \(a,b,c\) 相乘。每个数 \(y\) 满足:

  • \(y> T\)\(y\) 是质数。
  • 否则 \(y\le T\)\(y\) 可以是合数。

因为 \(x\) 可能有至多一个质因子 \(p> T\),如果有,则把 \(x\) 分成 \(p\)\(q\)\(q\) 一定是一个 \(\le T\) 的数,否则 \(pq\)\(\ge (T+1)^2\) 了。那么把 \(q\) 拆成两个数也一定都是 $\le T $ 的。如果没有,假设存在一个合数 \(>T\),那么另外两个数的乘积一定 \(\le T\),否则他们三乘起来就 \(\ge (T+1)^2\) 了。这时候我们把两个小的数乘起来变成一个,然后把大的合数拆开就好了。emm,感性理解一下吧。

不是,我为什么要证明这个东西啊,学 OI 还纠结什么证明?

好的,接下来我们不再证明这些显然的东西了。

O(n) 预处理

线性筛筛出每个数的最小质因数 \(p\),然后这个数的分解方式复制 \(x/p\) 的分解方式,然后从 \(a,b,c\) 依次判断能否乘上 \(p\) 之后仍然合法,合法就乘上好了。

线性同余方程

\[ax \equiv b (\bmod n) \]

给定 \(a,b,n\),求 \(x\)\([0,n-1]\) 的整数解。

\(a,n\) 互素时,可以逆元求解。

\[x \equiv b a^{-1} (\bmod n) \]

\(a,n\) 不互素,此时不一定有解。当且仅当 \(\gcd (a,n) | b\) 的时候有解且恰有 \(\gcd(a,n)\) 个解,可以感性理解。使用逆元或者扩展欧几里得算法求解。

逆元求解

\(g=\gcd(a,n)\)

方程左右及模数同除 \(g\)

\(a'=\frac{a}{g},b'=\frac{b}{g},n'=\frac{n}{g}\)
\(a' x' \equiv b' (\bmod n')\)

可以发现 \(x'\) 也是原方程的一个解。

原方程有 \(g\) 个解。通解为 \(x_i = x'+in'(i \in [0,g-1])\)

显然这样的解是新方程的解,又因为这样的解 \(\le n-1\),因此这样的解也是原方程的解。

扩展欧几里得算法

同余方程

\[ax \equiv c (\bmod b) \]

可以转化为

\[ax + by = c \]

当且仅当 \(\gcd(a,b)| c\) 的时候有且有 \(\gcd(a,b)\) 个解。

假设 \(gcd(a,b) | c\),设 \(g=gcd(a,b)\)

方程

\[\frac{a}{g} x + \frac{b}{g} y = \frac{c}{g} \]

的解集和原方程相等。

上面的方程写作

\[a' x + b' y = c'(\gcd(a',b')=1) \]

我们先求方程 \(a' x + b' y = \gcd (a', b')\) 的解。

\(b'=0\) 的时候,显然有 \(\gcd=a',x=1,y=0\)

\(b > 0\) 的时候,参考辗转相除法的过程。求出方程 \(b' x' + (a' \bmod b') y' = \gcd\) 的解。有

\[b' x' + (a' \bmod b') y' = a' x + b' y\\ b' x' + (a' - b' \lfloor \frac{a'}{b'} \rfloor) y' = a' x + b' y\\ b' x' + a'y' - b' \lfloor \frac{a'}{b'} \rfloor y' = a' x + b' y\\ a'y' + b'(x' - \lfloor \frac{a'}{b'} \rfloor y') = a' x + b' y\\\]

由此得出

\[x=y'\\ y=x' - \lfloor \frac{a'}{b'} \rfloor y'\]

素数和合数

一个数有且仅有 \(1\) 和它本身两个因子,这个数是素数,因此 \(1\) 不是素数。

线性筛法

每个数只会被最小的质因子筛到。

复杂度 \(O(n)\)

Code

#include<bits/stdc++.h>
#define ll long long
#define pf printf
#define sf scanf
using namespace std;
const int N=1e6+7,M=1e7;
int can[N];
int p[M];
void primes(int n){
	for(int i=2;i<=n;i++){
		if(!p[i]){
			p[i]=i;
			can[++can[0]]=i;
		}
		for(int j=1;j<=can[0];j++){
			if(can[j]>p[i]||(ll)can[j]*i>n) break;
			p[can[j]*i]=can[j];
		}
	}
}
int main(){
	int n=M;
	primes(n); 
	pf("%d\n",can[0]);
}

乘法逆元

\[ax \equiv 1 (\bmod p) \]

\(x\)\(a\) 的乘法逆元。

\(a,p\) 不互素,则不存在乘法逆元。

线性求逆元

求连续逆元

结论、证明见 OIWiki。这里搬一张结论。

附上可爱代码:

inv[1]=1;
rep(i,2,n) inv[i]=1ll*(p-p/i)*inv[p%i]%p;

求任意 n 个数的逆元

\(s_n\) 表示前 \(n\) 个数的积(取模意义下),先求出 \(s_n^{-1}\),然后倒序一次求出 \(s_i^{-1}\),最后 \(inv_i \gets s_i^{-1} \times s_{i-1}\)

s[0]=1;
rep(i,1,n) s[i]=1ll*s[i-1]*a[i]%p;
sinv[n]=ksm(s[n],p-2);
per(i,n-1,0) sinv[i]=1ll*sinv[i+1]*a[i+1]%p;
rep(i,1,n) inv[i]=1ll*sinv[i]*s[i-1]%p;
posted @ 2024-08-14 18:30  liyixin  阅读(33)  评论(0编辑  收藏  举报