数论基础部分

改名!感觉还是把数学都写到这里吧。

数学菜批是这样的。

数论分块

算是前置芝士了,很多莫反题都要用这玩意。

假如现在我们有 $\left \lfloor \frac{n}{i} \right \rfloor $ 这样的式子,能够发现,其实他会有一大段值的取值是一样的,比如令 \(n = 30\),那么从 \(8\)~\(10\) 的取值都是相同的,当 \(n\) 很大的时候,这个块的长度也会很大,某些题中,我们只需要用到他的取值,那么我们遍利所有的 \(i\) 显然是冗余的,只要找到每一个块的右端点挨个看就好了,现在考虑如何找这个右端点。

甩个结论 $\left \lfloor \frac{n}{\left \lfloor \frac{n}{i} \right \rfloor } \right \rfloor $ 就是右端点,考虑证明。

首先令 $k = \left \lfloor \frac{n}{i} \right \rfloor $,那么显然 \(k \leq \frac{n}{i}\),那么就会有 $\left \lfloor \frac{n}{k} \right \rfloor \ge \left \lfloor \frac{n}{\frac{n}{i}} \right \rfloor = \left \lfloor i \right \rfloor = i $,感性理解,当 \(i\) 取到最靠右的值的时候,就是 $\left \lfloor \frac{n}{k} \right \rfloor $,也就证明了上面的结论,所以数论分块的代码写出来也是非常简洁的。

例题 P3579 [POI2014] PAN-Solar Panels

好像是因为这个题才来写的这个笔记

不是很板,带一点思考量,我们首先能够发现,假如有一个 \(gcd\) 能满足答案,感性来看就是他一定会被同时包含在 \([a,b]\)\([c,d]\) 中间,那么如果要判断这个答案,就是令 $\left \lfloor \frac{a}{i} \right \rfloor < \left \lfloor \frac{b}{i} \right \rfloor $ 时才能满足条件,\([c,d]\) 同理。那么现在就是要考虑怎么判断令 \(i\) 同时满足两个不等式了,这就可以考虑上面的整除分块了,我们只需要枚举商,判断是否被区间包含即可,复杂度 \(O(n \sqrt V)\)

code

莫比乌斯反演

我总算是懂了,现在给一个莫比乌斯函数。

\[\mu(x)= \left\{\begin{matrix} 1 & n=1 & \\ 0 & n有平方因子 & \\ (-1)^k & k为本质不同的因子个数 & \end{matrix}\right.\]

基于没有平方因子的性质,我们可以用欧拉筛求这东西,具体就是:

inline void GP(ll n){
	vis[1]=1;mu[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]) prime[++cnt]=i,mu[i]=-1;
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
			vis[i*prime[j]]=1;
			if(i%prime[j]==0) break;
			mu[i*prime[j]]=-mu[i]; 
		}
	}
	fo(2,i,n) mu[i]+=mu[i-1];
}

莫比乌斯函数还有个性质:

\[\sum_{d|n}\mu(d)=\left\{\begin{matrix} 1& n=1 & \\ 0& n\neq1 & \end{matrix}\right.\]

也就是他等价于 \(\zeta (n)\)\(\mu * 1 = \zeta\),其中 \(\zeta\) 是黎曼函数,\(*\) 是狄利克雷卷积,所以在狄利克雷生成函数里面,莫比乌斯函数等价于常值函数 \(1\) 的逆元。

啊啊啊,好多笔误。

考虑证明:

\(n = \prod_{i=1}^{k} p_i^{c_i}\)\({n}'=\prod_{i=1}^{k} p_i\)

显然,由二项式定理:

\[\sum_{d|n}\mu(d)=\sum_{d|{n}'}\mu(d)=\sum_{i=0}^{k}\binom{k}{i}\times (-1)^i = (1+(-1))^k \]

所以当且仅当 \(k=0\) 时原式值为 \(1\),也就是仅当 \(n=1\) 时成立。

有个小结论,这个还是很好理解的,\([\gcd(i,j)=1] = \sum_{d|\gcd(i,j)} \mu(d)\)

现在有了上面的结论,我们开始莫反的推导,假设现在有两个在非负数域上定义的函数 \(f(i)\)\(F(i)\),并且有 \(F(n) = \sum_{d|n} f(d)\),那么我们存在反演结论 \(f(n) = \sum_{d|n} \mu(d)F(\left \lfloor \frac{n}{d} \right \rfloor)\)

考虑证明,首先有:

\[\sum_{d|n} \mu(d)F(\left \lfloor \frac{n}{d} \right \rfloor) = \sum_{i|n} \mu(i)\sum_{d|\left \lfloor \frac{n}{i} \right \rfloor} f(d) \]

这一步只是将式子变了一下,然后我们更换顺序:

\[\sum_{i|n} \mu(i)\sum_{d|\left \lfloor \frac{n}{i} \right \rfloor} f(d) = \sum_{i|n} f(i) \sum_{d|{\left \lfloor \frac{n}{i} \right \rfloor}} \mu(d) \]

然后由莫比乌斯函数的性质可以得知,当且仅当 \(\left \lfloor \frac{n}{i} \right \rfloor = 1\) 的时候,后半部分的式子才不为 \(0\),此时才代回前面式子,可以得到:

\[\sum_{i|n} f(i) \sum_{d|n} \mu(d) = f(n) \]

得证。

其实莫反还有一种形式结论 \(f(n) = \sum_{d|n} \mu(\frac{n}{d})F(d)\),这种也是好证明的。

到这里就差不多了,还有一些例题,之后会慢慢补上的。

P3455 [POI2007] ZAP-Queries

写出原答案式子:

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

\(k\) 提出来扔到前面去:

\[\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{k} \right \rfloor} [\gcd(i,j) = 1] \]

直接莫反:

\[\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{k} \right \rfloor} \sum_{d|{\gcd(i,j)}} \mu(d) \]

再改一下枚举顺序:

\[\sum_{d=1}^{n} \sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{kd} \right \rfloor} \mu(d) \]

发现 \(\mu(d)\) 可以扔到前面去,那后面一坨就没什么意义了:

\[\sum_{d=1}^{n} \mu(d) \left \lfloor \frac{n}{kd} \right \rfloor \left \lfloor \frac{m}{kd} \right \rfloor\]

筛一下 \(\mu(d)\) 这样我们就有了 \(O(n)\) 的解决办法,可是是多组,这样显然过不去。

进一步考虑数论分块,现将 \(n\)\(m\) 除以 \(k\) 之后就是数论分块的一般形式了,直接套板子求个和就好了,复杂度 \(O(n\sqrt n)\)

code

P2398 GCD SUM

双倍经验,还是上面那个式子,枚举一下 \(\gcd(i,j)\) 的值就好了。

P1829 [国家集训队] Crash的数字表格 / JZPTAB

晚自习 40min 搞出来了,但是式子长的要死。

写出原式子 \(\sum_{i=1}^{n} \sum_{j=1}^{m} \operatorname{lcm} (i,j)\),把 lcm 拆开,写成 \(\sum_{i=1}^{n} \sum_{j=1}^{m} \frac{ij}{\gcd(i,j)}\)

感觉这个分数形式很难搞,我们仍然采用枚举 gcd 的想法搞,这里跳了一步,直接把 \([\gcd(i,j) = k]\) 弄到外面去,然后会留下 \(k^2\) 的常数:

\[\sum_{k=1}^{n} \frac{1}{k} \sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor} \sum_{j=1}^{\left \lfloor \frac{m}{k} \right \rfloor} k^2 ij [\gcd(i,j) = 1] \]

\(k^2\) 放到外面,然后常规莫反套路,改一下 gcd 式子再莫反:

\[\sum_{k=1}^{n} k \sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor} \sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor} \sum_{j=1}^{\left \lfloor \frac{m}{kd} \right \rfloor} d^2ij~\mu(d) \]

之后把无关的 \(d^2\mu(d)\) 扔出去,发现 \(i\) 与后面的一个求和无关,放到前面:

\[\sum_{k=1}^{n} k \sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor} d^2\mu(d) \sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor} i \sum_{j=1}^{\left \lfloor \frac{m}{kd} \right \rfloor} j \]

这样的话,我们可以处理 \(A_i = \sum_{j=1}^{i} j\) 就可以把式子表示成:

\[\sum_{k=1}^{n} k \sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor} d^2\mu(d) A_{\left \lfloor \frac{n}{kd} \right \rfloor} A_{\left \lfloor \frac{m}{kd} \right \rfloor} \]

把后面记作 \(f(n) = \sum_{d=1}^{n} d^2\mu(d) A_{\left \lfloor \frac{n}{d} \right \rfloor} A_{\left \lfloor \frac{m}{d} \right \rfloor}\),这东西只要预处理 \(\sum \mu(d) d^2\) 就可以数论分块了,复杂度 \(O(\sqrt n)\)

可是还有前面枚举 \(k\)\(O(n)\),这样总的是 \(O(n\sqrt n)\),无法通过。

写出式子 \(\sum_{k=1}^{n} k~f(\left \lfloor \frac{n}{k} \right \rfloor)\),发现这东西可以再套一个数论分块,这样总的复杂度就是 \(O(n)\) 了,可以通过。

code

P2257 YY的GCD

滚回来更新了,这题好像四个月前就在做题计划里了,一直没补(

好像有一个单测的简化版,简单写一下式子吧,我们默认令 \(n < m\)

\[\sum_{k \in prime} \sum_{i=1}^{\left \lfloor \frac{n}{k}\right \rfloor} \sum_{i=1}^{\left \lfloor \frac{m}{k}\right \rfloor} [\gcd(i,j) = 1] \]

然后莫反:

\[\sum_{k \in prime} \sum_{d=1}^{\left \lfloor \frac{n}{k}\right \rfloor} \sum_{i=1}^{\left \lfloor \frac{n}{kd}\right \rfloor} \sum_{i=1}^{\left \lfloor \frac{m}{kd}\right \rfloor} \mu(d) \]

\(\mu(d)\) 提到前面去,自然变成:

\[\sum_{k \in prime} \sum_{d=1}^{\left \lfloor \frac{n}{k}\right \rfloor} \mu(d) \left \lfloor \frac{n}{kd}\right \rfloor \left \lfloor \frac{m}{kd}\right \rfloor \]

这样单次时间复杂度就是 \(O(V\sqrt n)\) 了,其中 \(V\) 表示 \(prime\) 的大小,可是这题多测,\(O(TV\sqrt n)\) 跑不过去,考虑再优化:

\(T=dk\),我们改为优先枚举 \(T\),则式子变成:

\[\sum_{T=1}^{n} \left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor \sum_{k|T,k \in prime} \mu (\left \lfloor \frac{T}{k} \right \rfloor) \]

这时候我们就发现后面的东西可以预处理了,在欧拉筛之后枚举一下倍数是 \(O(n\log n)\) 的。

code

P3704 [SDOI2017] 数字表格

大力膜拜 lhc!!!

写出式子,默认 \(n < m\)\(f(i)\) 表示 fib 序列:

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

枚举 \(\gcd\),得到:

\[\prod_{d=1}^{n} \prod_{j=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \prod_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor} f(d)^{[gcd(i,j)=1]} \]

发现 \(f(d)\) 进行乘法的次数就是 \(\sum_{i=1}^n \sum_{j=1}^m [gcd(i,j)=1]\)

\[\prod_{d=1}^{n} f(d)^{\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \sum_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor} [gcd(i,j)=1] } \]

之后正常莫反套路:

\[\prod_{d=1}^{n} f(d)^{\sum_{k=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \mu(k) \left \lfloor \frac{n}{kd} \right \rfloor \left \lfloor \frac{m}{kd} \right \rfloor} \]

然后我们里面的 \(\sum\) 拿出来,对里面分成两部分:

\[\prod_{d=1}^{n} \prod_{k=1}^{\left \lfloor \frac{n}{d} \right \rfloor} (f(d)^{\mu(k)})^{\left \lfloor \frac{n}{kd} \right \rfloor \left \lfloor \frac{m}{kd} \right \rfloor} \]

模仿上一题的优化套路,我们先令 \(T=kd\),然后枚举 \(T\),改一下式子:

\[\prod_{T=1}^{n} (\prod_{d|T} f(d)^{\mu(\frac{T}{d})})^{\left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor} \]

我们设 \(F(n) = \prod_{d|n} f(d)^{\mu(\frac{n}{d})}\),原式变成:

\[\prod_{T=1}^n F(T)^{\left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor} \]

因为 \(n\leq 10^6\),所以 \(F(T)\) 是可以枚举因数做到预处理 \(O(n\log n)\) 的,再做一遍数论分块就好了,复杂度大概是 \(O(T\sqrt n \log n)\)

code

扩展欧几里得算法

求解不定方程,形似 \(ax + by = \gcd(a,b)\) 的解。

洛谷的模板题是求 \(ax+by =c\),因为显然有 \(\gcd(a,b) | (ax+by)\),然后就要保证 \(\gcd(a,b) | c\),把通解形式改写一下就好了。

感觉 oi-wiki 的证法比较好理解,写一下:

我们设:

存在 \(ax_0 + by_0 = \gcd(a,b)\)\(bx_1 + (a \mod b)y_1 = \gcd(b,a \mod b)\)

要证明这俩方程是等价的,首先有 \(\gcd(a,b) = \gcd(b,a\mod b)\),然后写成 \(ax_0 + by_0 = bx_1 + (a\mod b)y_1\)

对于 \(a\mod b\),等价于 \(a = a - \left \lfloor \frac{a}{b}\right \rfloor \times b\)

推一下式子,有 \(ax_0 + by_0 = ay_1 + b(x_1 - \left \lfloor \frac{a}{b}\right \rfloor y_1 )\)

那么就有 \(x_0 = y1\)\(y_0 = x_1 - \left \lfloor \frac{a}{b}\right \rfloor y_1\),递归求解即可。

inline ll Exgcd(ll a,ll b,ll &x,ll &y)
{
	if(!b) return x=1,y=0,a;
	ll d=Exgcd(b,a%b,x,y);
	ll t=x;x=y,y=t-(a/b)*y;return d;
}

卢卡斯定理

对于一个质数 \(p\),我们可以用卢卡斯定理求 \(\binom{n}{m}\mod p\)

有结论是 $Lucas(n,m)=Lucas(n/p,m/p) \times \binom{n \mod p}{m \mod p} $,这个是直接递归下去求就好了,复杂度大概是 \(O(\log n)\)

等我尽量补一下证明。

inline ll qpow(ll a,ll b){return (!b?1ll:qpow(a*a%p,b>>1)*((b&1ll)?a:1ll))%p;}
inline ll C(ll n,ll m){if(m>n) return 0;return pre[n]*qpow(pre[m],p-2)%p*qpow(pre[n-m],p-2)%p;}
inline ll Lucas(ll n,ll m){return (!m?1ll:C(n%p,m%p)*Lucas(n/p,m/p)%p);}
signed main(){
	ll t;read(t);
	while(t--)
	{
		read(n),read(m),read(p);
		pre[0]=1;fo(1,i,max(n+m,p)) pre[i]=pre[i-1]*i%p;
		wr(Lucas(n+m,n)),pr; 
	}
}

扩展欧拉定理

哦这个好久之前就写过博客了,写的好丑啊我靠。

欧拉函数

这里给出定义 :

我们记 \(\varphi(n)\) 为小于等于\(n\)\(n\)互质的数的个数。

展开是这样的:

\(\varphi(x) = \sum_{i=1}^{x} [~\gcd~(i,n)=1]\)

欧拉筛显然可以把它筛出来:

inline void check_mul(ll n){
	vis[1]=1,mul[1]=1;
	fo(2,i,n)
	{
		if(!vis[i]) prime[++cnt]=i,f[i]=i,mul[i]=-1;
		for(ll j=0;j<cnt&&i*prime[j]<=n;j++){
			vis[i*prime[j]] = 1;
			f[i*prime[j]] = f[i] + 1;
			if(i%prime[j]==0){
				mul[i*prime[j]]=0;
				break;
			}
			mul[i*prime[j]]=-mul[i];
		}
	}
}

对于单个欧拉函数的求法:

欧拉函数是特殊的积性函数,有性质 \(\varphi(ab) = \varphi(a) \varphi(b)\),对于任意一个正整数 \(a\),有 \(a = \prod_{i=1}^n p_i^{k_{i}}\)

进一步,我们可以发现对于任意一个质数 \(p\),有 \(\varphi(p^k) = p^{k-1} (p-1)\)

因此,有 \(\varphi(a) = \prod_{i=1}^n \varphi(p_i^{k_i}) = \prod_{i=1}^n p_i^{k_i-1}(p_i-1) = \prod_{i=1}^n p_i^{k_i} \prod_{i=1}^n (1-\frac{1}{p_i}) = a \prod_{i=1}^{n} (1-\frac{1}{p_i})\)

这样我们就可以在 \(O(\sqrt a)\) 的复杂度内处理出 \(\varphi(a)\)

欧拉定理

直接给出结论:

\(gcd(a,m)=1\) , 则有 \(a^{\varphi(m)}\equiv 1\) \((mod\) \(m)\)

证明比较简单:

我们假定 \(r_1,r_2,r_3...r_{\varphi(m)}\) 为模 \(m\) 下的一个剩余系,则 \(ar_1,ar_2...ar_{\varphi(m)}\) 也为模 \(m\) 下的一个剩余系,所以有 \(r_1\cdot r_2 \cdot r_3 \cdot ... \cdot r_{\varphi(m)}\equiv ar_1 \cdot ar_2 \cdot ar_3 \cdot ... \cdot ar_{\varphi(m)}\) 同时约去剩余系 , 即可得到上述公式 \(a^{\varphi(m)}\equiv 1\) \((mod\) \(m)\)

具体证明可以参考 oiwiki

拓展欧拉定理

对于欧拉定理,只有在 \(gcd(a,m)=1\) 时才能使用,那么我们推广一下便可得到:

\[ a^b \equiv \left \{ \begin{matrix} a^{b\mod \varphi(p)}, & \gcd(a,p) = 1,\\ a^b, & \gcd(a,p) \neq 1,b < \varphi(p), \pmod p\\ a^{b \mod \varphi(p) + \varphi(p)}, &\gcd(a,p) \neq 1,b \geq \varphi(p) \end{matrix}\right. \]

证明过程类似跳循环节,此处不再写。

那么,我们只需要预处理出 \(\varphi(m)\) 就可以按照拓展欧拉定理进行降幂了。

inline bool read(ll &opp,ll mod){ll x=0,t=1;char ch;ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-'){t=-1;}ch=getchar();}ll flag=0;while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);if(x>=mod) flag=1,x%=mod;ch=getchar();}opp=x*t;return flag;}
inline void wr(ll x){if(x<0){putchar('-');x=-x;}if(x>9){wr(x/10);}putchar(x%10+'0');}
inline ll qpow(ll a,ll b,ll mod){return (!b?1ll:qpow(a*a%mod,b>>1,mod)*((b&1)?a:1ll))%mod;}
ll a,m,b;
signed main(){
	read(a),read(m);
	ll k=m,phi=m;
	fo(2,i,sqrt(m))
	  if(k%i==0)
	  {
		phi=phi/i*(i-1);
		while(k%i==0) k/=i;
	  }
	if(k>1) phi=phi/k*(k-1);
	ll op=read(b,phi);if(op) b+=phi;
	wr(qpow(a,b,m)),pr;
}

中国剩余定理(CRT)

考虑我们现在有同余方程组:

\[\left\{\begin{matrix} x \equiv a_1 \pmod {b_1} \\ x \equiv a_2 \pmod {b_2} \\ ... \\ x \equiv a_n \pmod {b_n} \end{matrix}\right. \]

对于这个方程组的求解,我们有结论:

\(n = \prod b_i\)\(m_i = \frac{n}{b_i}\)\(c_i = m_i (m_i^{-1} \mod b_i)\)

则有 \(ans = \sum a_i c_i\)

考虑证明,我们要证明 \(ans \equiv a_i \pmod{b_i}\)

对于任意 \(i\neq j\),显然有 \(m_j \equiv c_j \equiv 0 \pmod{b_i}\),而又有 \(c_i \equiv m_i (m_i^{-1} \mod b_i) \equiv 1 \pmod{b_i}\)

于是就可以推到出,对于每一个 \(i\),有:

\[\sum a_i c_i \equiv a_ic_i \equiv a_i m_i (m_i^{-1} \mod b_i) \equiv a_i \pmod{b_i} \]

得证,CRT 的正确性就是需要 \(b_i\) 互质,不互质的话就需要 exCRT 了,求 \(m^{-1}\) 时需要用到 exgcd。

inline ll Exgcd(ll a,ll b,ll &x,ll &y)
{
	if(!b) return x=1,y=0,a;
	ll d=Exgcd(b,a%b,x,y);
	ll t=x;x=y,y=t-(a/b)*y;return d;
}
signed main(){
	read(n);fo(1,i,n) read(a[i]),read(b[i]),sum*=a[i];
	fo(1,i,n)
	{
		ll opt=sum/a[i],x,y;
		Exgcd(opt,a[i],x,y);
		ans=(ans+b[i]*opt*x%sum)%sum;
	}
	wr((ans%sum+sum)%sum),pr;
}
posted @ 2025-02-18 16:17  Wei_Han  阅读(46)  评论(1)    收藏  举报