Part 1【同余相关、phi&u】

答案是会什么,什么都不会。

1.Exgcd

裴蜀定理:\(ax+by=c\) 有解当且仅当 \(c=k \times (a,b)\)。整数条件下。

推广:

对于任意 \(x_1,x_2,...,x_m\)。当 \((a_1,a_2,...,a_m) | c\) 有解。应用见 CF19xxD。

现在我们要得到 \(ax+by=c\) 的一个解。不妨先解 \(c=(a,b)\),再乘一个系数。

考虑 gcd 的辗转相除法:\((a,b)=(b,a\bmod b)\)

所以我们有:\(ax+by=(a,b),bx'+(a\bmod b)y'=(b,a\bmod b)\)

注意,这里 \(x',y'\) 是根据 \((b,a\bmod b)\) 得到的,我们需要还原使得 \(x,y\) 对应 \((a,b)\)

所以 \(ax+by=bx'+(a\bmod b)y'=ay'+b(x'-\lfloor \frac{a} {b}\rfloor y')\)

那么递归求解,取 \(x=y',y=x'-\lfloor \frac{a} {b}\rfloor y'\) 即可。

边界?普通 gcd 可知 \(b_0=0,a_0=(a,b)\),此时取 \(x_0=1,y_0=0\) 即满足。(此时 \(b\) 直接是 \(0\) 了,所以变成了 1 元方程)

void exgcd(int a, int b, int &x, int &y) {
	if(!b) return x = 1, y = 0, void();
	exgcd(b, a % b, y, x), y -= a / b * x;
}

1.1 通解

直接给出结论:设 \(d=(a,b)\)

\(x=x_0+\frac{b}{d}k,\) \(y=y_0-\frac{a}{d}k\)

可以根据这个求范围内的最大最小值,解的个数等信息……

并且该算法有一个性质就是你求得的 \(x,y\) 满足在所有解中 \(|x|+|y|\) 最小。

1.2 应用

  1. 转化方程 \(ax\equiv b \pmod p\) 为二元一次方程求解,比如求逆元。也可以根据这个知道使用条件是 \(a\bot p\)

1.3 例题

先鸽。

2. BSGS

求解方程

\[a^x\equiv b\pmod p \]

2.1 特殊情况

一个很重要的前提:\(x\) 一定在 \([0,p)\) 有解。

\(x=AM-B(B \in [0,M))\),类似除和模。变形:\(a^{AM}\equiv ba^B\pmod p\)

\(M=\sqrt p\)。那么右边就只有根号种取值,左边也只有根号种取值。

那就简单了,预处理出左边,枚举右边即可,由于可能要用 map,所以复杂度根号对数。

2.2 ExBSGS

注意上面的算法有一个前提:\(a\bot p\)

why?因为你把 \(a^B\) 移过去需要这个前提,否则显然不成立。

那干脆就强制改成互质。每次对一个 \(a\)\(p\) 除以 gcd \(D\)

\[\frac{a}{D}a^{x-1}\equiv \frac{b}{D}\pmod {\frac{p}{D}} \]

你把 \(a/D\) 移过去,因为和 \(p/D\) 互质所以可以用 exgcd 求逆元。

注意到 \(a\)\(p/\gcd(a,p)\) 不一定互质,所以要一直循环下去做,直到 \(a\bot p\)

注意取模,特判 \(b=1\) 返回 \(0\)

时间复杂度 \(O(\sqrt p+\log^2 p)\)。代码中 BSGS 返回了最小的 \(x\)

int qkpow(int a, int b, int Mod) {
	if(!b) return 1;
	if(b & 1) return a * qkpow(a, b - 1, Mod) % Mod;
	int t = qkpow(a, b >> 1, Mod); return t * t % Mod;
}

void exgcd(int a, int b, int &x, int &y) {
	if(!b) return x = 1, y = 0, void();
	exgcd(b, a % b, y, x), y -= a / b * x;
}
int inv(int x, int p) { int sb; exgcd(x, p, sb, *new int); return (sb % p + p) % p; }

map <int, int> mp;
int BSGS(int a, int b, int p) {
	int A = 1, B = sqrt(p) + 1; mp.clear();
	for(int i = 1; i <= B; i++) mp[(A = A * a % p) * b % p] = i;
	for(int i = 1, AA = A; i <= B; i++, AA = AA * A % p)
		if(mp[AA]) return i * B - mp[AA];
	return -1;
} 

void ExBSGS(int a, int b, int p) { // 最终要使得 a, p 互质 
	int s = 0; a %= p, b %= p; 
	while(__gcd(a, p) != 1) {
		if(b == 1) return printf("%lld\n", s), void();
		int D = __gcd(a, p);
		if(b % D) return puts("No Solution"), void();
		b /= D, p /= D; b = b * inv(a / D, p) % p;
		++s; a %= p;
	}
	
	int ans = BSGS(a, b, p);
	if(ans == -1) puts("No Solution");
	else printf("%lld\n", ans + s);	
}

3. CRT

中国剩余定理。中国真是太厉害啦。

3.1 互质情况

即,\(\forall i\neq j,m_i\bot m_j\)

勾石。

\(X=\sum a\times c\),考虑方程 \(i\)\(X=\sum\limits_{j\neq i}a_jc_j + a_ic_i\),要求前面一坨无关,即是 \(m_i\) 的倍数。而 \(c_i\) 却不能是 \(m_i\) 的倍数。

给出构造:\(c_i=\dfrac{M}{m_i}\),其中 \(M=\prod m_i\)

发现不够,还需要一个 \(d_i\),因为每个方程要有:\(a_ic_id_i\equiv a_i \pmod {m_i}\),那么自然就有 \(d_i\)\(c_i\)\(m_i\) 的逆元。因为 \(m_i\) 不一定质数,而 \(c_i\)\(m_i\) 互质。

最后 \(x=\sum a_ic_id_i\)

3.2 ExCRT

任意 \(m_i\)

核心思想是每次只合并 2 个方程。

首先对于 \(x\equiv a_1\pmod {m_1}\),有 \(x=k_1m_1+a_1\);代入第二个方程:\(k_1m_1+a_1=k_2m_2+a_2\)

那么就有 \(k_1m_1-k_2m_2=a_2-a_1\),exgcd 求即可。

又一个问题,\(x\equiv a_1\pmod {m_1}, x\equiv a_2\pmod {m_2}\) 合并后,\(m\) 怎么变?结论:\(\operatorname{lcm}(m_1,m_2)\)

所以新方程:\(x\equiv k_1m_1+a_1\pmod {\operatorname{lcm}(m_1,m_2)}\)。后面是个常数。

加入一个方程合并一次到最后就好了。

cin >> n >> b1 >> a1; bool flag = 1;
for(int i = 2, a2, b2;i <= n; ++i) {
	b2 = read(), a2 = read(); if(!flag) continue ;
	if((a2 - a1) % __gcd(b1, b2)) { flag = 0; continue ; }
	int GCD = __gcd(b1, b2); int k = ((a2 - a1) % b2 + b2) % b2 / GCD;
	int x; exgcd(b1 / GCD, b2 /= GCD, x, *new int); x = (x % b2 + b2) % b2;
	x = (__int128)x * k % b2;
	a1 += x * b1, b1 *= b2, a1 = (a1 % b1 + b1) % b1;
}

注意上面代码中 \(b\) 代表 \(m\)

难绷。

3.3 例题

古代猪文

用费马小定理的话,发现模数是个偶数,搞不了。

所以把这个模数拆成多个质因子,每个单独求答案,最后 CRT 还原出来即可。

屠龙勇士

几乎板子?

预处理一下,然后就是多个 exgcd 的方程,变一下就是 excrt 了。记得和某个值取 max。

4.欧拉函数

4.1 定义

\(\varphi(n)\) 定义为 \([1,n]\) 中于 \(n\) 互质的数。

4.2 性质

4.2.1 性质一

\(p\) 为质数,则 \(\varphi(p)=p-1\)

4.2.2 性质二

\(p\) 为质数,则 \(\varphi(p^k)=(p-1)p^{k-1}\)

考虑 \([1,p^k]\) 中有多少个是 \(p\) 的倍数,减去即可,共 \(p^{k-1}\) 个。

4.2.3 性质三

\(a\) \(\bot\) \(b\),则 \(\varphi(ab)=\varphi(a)\times \varphi(b)\)

4.2.4 性质四

\(a\mid b\),则 \(\varphi(ab)=a\times \varphi(b)\)

3 和 4 可以感性理解。或者直接用 4.2.5 即可。

4.2.5 性质五

\(n\) 的唯一分解为:\(n=\prod\limits _{i=1}^k p_i^{c_i}\),则 \(\varphi(n)=n\times \prod\limits _{i=1}^k \dfrac{p_i-1}{p_i}\)

反复用上面的性质证就可以了。

根据这个,可以根号地求出单个欧拉值。

4.2.6 性质六

\(\varphi(\dfrac{n}{d})=\sum\limits_{i=1}^n [\gcd(i,n)=d]\)

考虑 \(\gcd(i,n)=d\) 的一个必要条件是 \(\dfrac{i}{d}\) \(\bot\) \(\dfrac{n}{d}\)。现在给定 \(n,d\),那么 \(i\) 的个数就是满足 \(\dfrac{i}{d}\) \(\bot\) \(\dfrac{n}{d}\) 的个数,即 \(\varphi(\dfrac{n}{d})\)

4.2.7 性质七 欧拉反演

\(\sum\limits _{d\mid n} \varphi(d) = n\)

首先 \(n=\sum\limits_{d\mid n}\sum\limits_{i=1}^n [(i,n)=d]\)

根据性质六:\(n=\sum\limits_{d\mid n}\varphi(\dfrac{n}{d})=\sum\limits_{d\mid n}\varphi(d)\)

4.2.8 性质八

对于 \(n>2\)\(2\mid \varphi(n)\)

知道 \(x\bot n\),则 \(n-x\bot n\) 即可。

4.2.9 性质九

\(a\mid b\),则 \(\varphi(a)\mid \varphi(b)\)

因为 \(b\) 包含了 \(a\) 的质因子,所以 \(p\) 那一坨的式子也满足整除关系。

4.3 线性筛欧拉函数

根据性质 3、4,再结合线性筛即可。

void init(int len) {
	phi[1] = f[1] = 1;
	for(int i = 2;i <= len; ++i) {
		if(!f[i]) p[++cnt] = i, phi[i] = i - 1;
		for(int j = 1;p[j] * i <= len and j <= cnt; ++j) {
			f[p[j] * i] = 1; phi[i * p[j]] = phi[i] * (p[j] - 1); 
			if(i % p[j] == 0)
				{ phi[i * p[j]] = p[j] * phi[i]; break;  } 
		}	
	}
}

4.4 欧拉定理

5. 莫比乌斯函数

本身也没什么好讲的,主要是狄利克雷卷积那一部分。

5.1 性质

5.1.1

  • \(\mu * 1 = \varepsilon\),即 \(\sum\limits _{d\mid n} \mu(d)=[n=1]\)非常重要。

考虑证明:

\(n\) 的所有 \(c_i\ge 2\) 的质因子去掉,得到 \(n'\)。可知 \(\mu(n)=\mu(n')。\)
\(n'=\prod\limits _{i=1}^kp_i\),故 \(\mu(n')=\sum\limits _{i=0}^k \dbinom{k}{i}(-1)^i=(1-1)^k\)
\(k=0\) 时特殊考虑,为 \(1\);其余恒为 \(0\)

由此我们看出 \(\mu\) 大致就是 \(1^{-1}\)

所以我们引出反演:

5.1.2

  • \(g=f*1\),则 \(f=g*\mu\)

根据欧拉反演:\(\operatorname{id}=\varphi * 1\)。可知:\(\varphi = id * \mu\),即:

\[\varphi(n)=\sum _{d\mid n}\mu(d)\frac{n}{d} \]

5.1.3

\[\sum _{i=1}^n\sum _{j=1}^m [\gcd(i, j) = 1] \]

\[=\sum _{i=1}^n\sum _{j=1}^m \sum_{d\mid n} \mu(d) \]

\[=\sum _{d=1}^{\min(n,m)}\mu (d)\sum _{i=1}^n\sum _{j=1}^m[d\mid i\land d\mid j] \]

\[=\sum _{d=1}^{\min(n,m)}\mu (d)\frac{n}{d}\frac{m}{d} \]

5.1.4

\(\large\sum\limits _{i=1}^n\sum\limits_{i=1}^m d(i\times j)\)

引理:\(\large d(i\times j)=\sum\limits_{x\mid i}\sum\limits_{y\mid j}[\gcd(x,y)=1]\)

证明考虑钦定选 \(y\) 的前提要选完 \(x\) 中所有 \(y\) 里面的质因子。而选 \(x\) 中的质因子则一定不能选 \(y\),这样就一一对应。

然后就是一些应用。

6. ex:线性筛求积性函数(一般)

因为自己唐完了。

记录 \(g(n)=p_1^{c_1}\),其中 \(p_1\)\(n\) 最小的质因子。(为什么记录 \(p_1\)?因为最先筛到,就这样)

当然,最开始 \(g(n)\) 最开始肯定 \(c_1\) 不对,需要动态更新。

然后可以根据积性函数性质更新了:

\(n=g(n)\),则 \(O(1)\) 直接计算即可;否则 \(f(n)=f(g(n))\times f(\dfrac{n}{g(n)})\)

注意一点,若 \((x,y)\neq 1\) 则不能直接积。

Hint

对于一般情况,积性函数一定可以用线性筛。但是,部分普通函数也可以用线性筛。如:P2257

在时间不卡的情况下,可以用埃氏筛轻松地求解任意函数,时间为 \(O(n\log\log n)\)

SP5971

注意积性函数性质:若 \(f\) 为积,则 \(f*1\) 也为积。

我们要求 \(g=f*1\),即 \(g(n)=\sum\limits _{d\mid n}f(d)\),那么 \(g\) 也满足积性函数性质。

这里 \(f(n)=n\varphi(n)\),显然是积。

注意上文有一个式子:

\[=\frac{1}{2}n(\varphi(n)+[n=1]) \]

后面那一坨要记得加上,然后 \(g(n)\) 计算时注意 \(d=1\)

posted @ 2024-07-17 15:15  LCat90  阅读(12)  评论(0编辑  收藏  举报