ICode9

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

数论初步

2021-03-04 15:01:06  阅读:168  来源: 互联网

标签:lfloor frac 数论 bmod rfloor 初步 int equiv


一些定理

裴蜀定理
若关于 \(x,y\) 的不定方程 \(ax+by=c\) 有解(\(a,b,c \in \mathbf{Z}\)),则 \(c \bmod \gcd(a,b) =0\) 。
费马小定理
若 \(p\) 为质数,且 \(\gcd(a,p)=1\) ,则 \(a^{p-1} \equiv 1 \pmod{p}\) 。
欧拉定理
若 \(\gcd(a,m)=1\) ,则 \(a^{\varphi(m)} \equiv 1 \pmod{m}\) 。
扩展欧拉定理
\(a^b \equiv \begin{cases} a^{b \bmod \varphi(p)}, & \gcd(a,p)=1 \\ a^b, & \gcd(a,p) \neq 1,b<\varphi(p) \\ a^{b \bmod \varphi(p)+\varphi(p)}, & \gcd(a,p) \neq 1, b \geq \varphi(p) \end{cases} \pmod p\)

exgcd

求关于 \(x\) , \(y\) 的方程 \(ax+by=\gcd(a,b)\) 的一组解。
设 \(ax_1+by_1=\gcd(a,b)\) , \(bx_2+(a \bmod b)y_2=\gcd(b,a \bmod b)\) 。
因为 \(\gcd(a,b)=\gcd(b,a \bmod b)\) ,
所以 \(ax_1+by_1=bx_2+(a \bmod b)y_2\) ,
所以 \(ax_1+by_1=bx_2+(a-\lfloor \frac{a}{b} \rfloor \cdot b)y_2\) 。
\(bx_2+(a-\lfloor \frac{a}{b} \rfloor \cdot b)y_2=ay_2+b(x_2-\lfloor \frac{a}{b} \rfloor \cdot y_2)\) ,
所以 \(ax_1+by_1=ay_2+b(x_2-\lfloor \frac{a}{b} \rfloor \cdot y_2)\) ,
所以 \(x_1=y_2\) , \(y_1=x_2-\lfloor \frac{a}{b} \rfloor \cdot y_2\) 。
注意到当 \(b=0\) 时令 \(x=1\) 即可得到解,以其为边界递归即可。

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

CRT

求解如下形式的方程组(其中,\(m_1,m_2,\cdots,m_k\) 两两互质):
\(\begin{cases} x & \equiv & a_1 \pmod{m_1} \\ x & \equiv & a_2 \pmod{m_2} \\ & \vdots \\ x & \equiv & a_k \pmod{m_k} \\ \end{cases}\)
令 \(M=\prod \limits_{i=1}^k m_i\) , \(w_i=\frac{M}{m_i}\) , \(w_i^{-1}\) 为 \(w_i\) 在模 \(m_i\) 意义下的逆元。
则 \(x_{min}=\sum \limits_{i=1}^k a_iw_iw_i^{-1} \bmod M\) 。

for(int i=1;i<=k;i++)
{
	int w=M/m[i];
	int x=0,y=0;
	exgcd(w,m[i],x,y);
	if(x<0) x+=m[i];
	ans+=a[i]*w*x%M,ans%=M;
}

exCRT

考虑上面的方程组中模数不互质的情况。
设当前求解到第 \(i\) 个方程,前 \(i-1\) 个方程的最小解为 \(x\) ,\(\operatorname{lcm}(m_1,m_2,\cdots,m_k)=M\) ,
则前 \(i-1\) 个方程的通解为 \(x+tM\) 。
那么,现在要找到一个 \(t\) ,使 \(x+tM \equiv a_i \pmod{m_i}\) 。
这个式子显然是可以使用 exgcd 求解的。
用裴蜀定理判一下无解。

for(int i=1;i<=n;i++)
{
	int res=(a[i]-X%m[i]+m[i])%m[i];
	int x=0,y=0;
	int d=exgcd(M,m[i],x,y);
	if(res%d) puts("-1"),exit(0);
	X+=x*res/d*M;//算上倍数,更新答案
	M*=m[i]/d,X+=M,X%=M;
}

Lucas

对于质数 \(p\) ,有 \(\displaystyle \binom{n}{m} \equiv \displaystyle \binom{\lfloor \frac{n}{p} \rfloor}{\lfloor \frac{m}{p} \rfloor} \cdot \displaystyle \binom{n \bmod p}{m \bmod p} \pmod p\) 。
在模数不大且为质数时,可以使用它来递归算组合数。

int lucas(int n,int m,int p)
{
	if(!m) return 1;
	return lucas(n/p,m/p,p)*C(n%p,m%p,p)%p;
}

代码中, C 函数为暴力算组合数。

exLucas

算模数非质数时的组合数。
先将模数 \(p\) 质因数分解,设 \(p=\prod \limits_{i=1}^k q_i^{a_i}\) (其中 \(q_i\) 为质数)。
可以构造出下面的同余方程组:
\(\begin{cases} \displaystyle \binom{n}{m} & \equiv & b_1 \pmod{q_1^{a_1}} \\ \displaystyle \binom{n}{m} & \equiv & b_2 \pmod{q_2^{a_2}} \\ & \vdots \\ \displaystyle \binom{n}{m} & \equiv & b_k \pmod{q_k^{a_k}} \\ \end{cases}\)
因为这个同余方程组的所有模数都互质,所以只要求出 \(b_{1 \cdots k}\) 即可用 CRT 求出 \(\displaystyle \binom{n}{m}\) 。
现在,问题转化为求 \(\displaystyle \binom{n}{m} \bmod p^k\) 的值(\(p\) 为质数) ,即 \(\frac{n!}{m!(n-m)!} \bmod p^k\) 的值。
但是,分母在模 \(p^k\) 意义下不一定有乘法逆元,所以要再进行一些转化。
设 \(n!\) 中包含 \(x\) 个 \(p\) 因子, \(m!\) 中包含 \(y\) 个 \(p\) 因子, \((n-m)!\) 中包含 \(z\) 个 \(p\) 因子,
则原式可以转化为 \(p^{x-y-z}\dfrac{\dfrac{n!}{p^x}}{\dfrac{m!}{p^y}\dfrac{(n-m)!}{p^z}} \bmod p^k\) 。
现在,问题又转化为求 \(\frac{n!}{p^x} \bmod p^k\) 的值 (\(p\) 为质数)。
对 \(n!\) 进行转化:
首先,把 \(n!\) 中所有为 \(p\) 的倍数的乘数和非 \(p\) 的倍数的乘数分开,\(n!=(p \times 2p \times 3p \times \cdots)(1 \times 2 \times 3 \times \cdots)\) 。
因为 \(1\) ~ \(n\) 中有 \(\lfloor \frac{n}{p} \rfloor\) 个 \(p\) 的倍数,所以进一步拆开,得 \(p^{\lfloor \frac{n}{p} \rfloor}(\lfloor \frac{n}{p} \rfloor)!\prod \limits_{i=1,i \bmod p \neq 0}^n i\) 。
因为模数为 \(p^k\) ,所以再把后半个式子每 \(p^k\) 个分成一组,得 \(p^{\lfloor \frac{n}{p} \rfloor}(\lfloor \frac{n}{p} \rfloor)!(\prod \limits_{i=1,i \bmod p \neq 0}^{p^k} i)^{\lfloor \frac{n}{p^k} \rfloor}(\prod \limits_{i=p^k \times \lfloor \frac{n}{p^k} \rfloor, i \bmod p \neq 0}^{n} i)\) 。
因为还要除以 \(p^x\) ,所以 \(p^{\lfloor \frac{n}{p} \rfloor}\) 一定没有了,但是, \((\lfloor \frac{n}{p} \rfloor)!\) 中为 \(p\) 的倍数的乘数也要除去。
设 \(f(x)=\frac{n!}{p^x}\) ,其中 \(x\) 同样代表 \(n!\) 中包含 \(p\) 因子的数目,
则 \(f(n)=f(\lfloor \frac{n}{p} \rfloor)(\prod \limits_{i=1,i \bmod p \neq 0}^{p^k} i)^{\lfloor \frac{n}{p^k} \rfloor}(\prod \limits_{i=p^k \times \lfloor \frac{n}{p^k} \rfloor, i \bmod p \neq 0}^{n} i)\) ,递归计算即可。
代回原式中,发现还有 \(p^{x-y-z}\) 无法计算,考虑如何计算 \(x,y,z\)。
下面以 \(\frac{n!}{p^x}\) 中的 \(x\) 为例。
设 \(g(x)=\) 上面的 \(x\) 。
观察前面化出的阶乘的式子,即可得到 \(g(n)=g(\lfloor \frac{n}{p} \rfloor)+\lfloor \frac{n}{p} \rfloor\) ,同样递归计算即可。

int f(int x,int p,int P)//P=p^k
{
	if(!x) return 1;
	int sum=1;
	for(int i=1;i<=P;i++)
		if(i%p) sum*=i,sum%=P;
	sum=POW(sum,x/P,P);
	for(int i=x/P*P;i<=x;i++)
		if(i%p) sum*=i%P,sum%=P;
	return f(x/p,p,P)*sum%P;
}
int g(int x,int p)
{
	if(!x) return 0;
	return g(x/p,p)+x/p;
}
int C(int n,int m,int p,int P)
{
	return f(n,p,P)*inv(f(m,p,P),P)%P*inv(f(n-m,p,P),P)%P*POW(p,g(n,p)-g(m,p)-g(n-m,p),P)%P;
}

代码中, POW 为快速幂函数,inv 为求逆元函数。

BSGS

求解方程 \(a^x \equiv b \pmod p\) ,其中 \(a,p\) 互质。
令 \(x=At-B\) (\(t\) 为定值),
则 \(a^{At-B} \equiv b \pmod p\) ,
因为 \(a,p\) 互质,所以 \(a^{At} \equiv ba^B \pmod p\) 。
可以枚举 \(B\) 的取值,存进 Hash 表中。
再枚举 \(A\) 的取值,判断 Hash 表中是否存在这个值,若存在,则找到了一个 \(x\) 的取值。
取 \(t=\lceil \sqrt p \rceil\) 时复杂度最优。
代码用 map 实现。

map <int,int> mp;
int t=ceil(sqrt(P));
int sum=b,s=1;
mp[sum]=0;
for(int i=1;i<=t;i++) sum*=a,sum%=P,s*=a,s%=P,mp[sum]=i;
sum=s;
for(int i=1;i<=t;i++)
{
	if(mp.count(sum)) printf("%lld",i*t-mp[sum]),exit(0);
	sum*=s,sum%=P;
}
puts("-1");

exBSGS

同样求解上面的方程,但是 \(a,p\) 不保证互质。
在 \(a,p\) 不互质时,不存在 \(a\) 在模 \(p\) 意义下的逆元,也就没有上面的推导。
考虑如何让 \(a,p\) 互质。
设 \(\gcd(a,p)=d_1\) ,方程两边同除以 \(d_1\) ,得到 \(\frac{a}{d_1} \cdot a^{x-1} \equiv \frac{b}{d_1} \pmod{\frac{p}{d_1}}\) ,
若当前还没有满足 \(a\) 与模数互质,则继续设 \(\gcd(a,\frac{p}{d_1})=d_2\) ,方程两边同除以 \(d_2\) ,得到 \(\frac{a}{d_1d_2} \cdot a^{x-1} \equiv \frac{b}{d_1d_2} \pmod{\frac{p}{d_1d_2}}\) ,
重复这样的操作,直到 \(a\) 与模数互质。
设进行了 \(k\) 次操作,每次操作时得到的 \(d\) 的乘积为 \(D\) ,
则当前方程转化为了 \(\frac{a^k}{D} \cdot a^{x-k} \equiv \frac{b}{D} \pmod{\frac{p}{D}}\) 。
此时,就可以用普通的 BSGS 求解了。
注意,每次操作过后要用裴蜀定理判一下无解,还要特判 \(x \leq k\) 的情况。

int BSGS(int x)
{
	mp.clear();
	int t=ceil(sqrt(P));
	int sum=b,s=1;
	mp[sum]=0;
	for(int i=1;i<=t;i++) sum*=a,sum%=P,s*=a,s%=P,mp[sum]=i;
	sum=x*s%P;
	for(int i=1;i<=t;i++)
	{
		if(mp.count(sum)) return i*t-mp[sum];
		sum*=s,sum%=P;
	}
	return -1;
}
int exBSGS()
{
	if(b==1||p==1) return 0;
	int k=0,sum=1;
	while(1)
	{
		int d=gcd(a,P);
		if(d==1) break;
		if(b%d) return -1;
		k++,b/=d,P/=d,sum*=a/d,sum%=P;
		if(sum==b) return k;
	}
	int ans=BSGS(sum);
	return (ans!=-1)*k+ans;
}

原根

:设 \(a,p\) 为两个正整数,且 \(\gcd(a,p)=1\) ,则使 \(a^x \equiv 1 \pmod p\) 成立的最小正整数 \(x\) ,即为 \(a\) 模 \(p\) 的阶,记作 \(\text{ord}_p a\) 。
设 \(g,a\) 为两个正整数,且 \(\gcd(g,a)=1\) ,若 \(\text{ord}_a g=\varphi (a)\) ,则 \(g\) 为 \(a\) 的一个原根。
若一个数有原根,则它一定可以表示为 \(2,4,p^k,2p^k\) 的形式(\(p\) 为奇质数,\(k\) 为任意正整数)。
若 \(g\) 为 \(a\) 的原根,则对于任意 \(\varphi(a)\) 的质因子 \(p\) ,都有 \(g^{\frac{\varphi(a)}{p}} \not \equiv 1 \pmod a\) 。
设 \(g\) 为 \(a\) 的最小原根,则集合 \(S=\{g^k | 1 \leq k \leq \varphi(a),\gcd(k,\varphi(a))=1\}\) 中的元素均为 \(a\) 的原根。
因此,一个数 \(a\) 有 \(\varphi(\varphi(a))\) 个原根,且这些原根模 \(a\) 两两不同余。
同时,若一个数 \(a\) 存在原根,则它的最小原根是不大于 \(a^{\frac{1}{4}}\) 级别的。所以求最小原根时可以直接枚举。

int find(int x)
{
	int tot=0;
	int X=phi[x];
	for(int i=2;i*i<=X;i++)
		if(X%i==0)
		{
			a[++tot]=i;
			while(X%i==0) X/=i;
		}
	if(X>1) a[++tot]=X;
	for(int i=1;;i++)
	{
		bool r=true;
		if(POW(i,phi[x],x)!=1) r=false;//原根的定义 
		for(int j=1;j<=tot;j++)
			if(POW(i,phi[x]/a[j],x)==1)
			{
				r=false;
				break;
			}
		if(r) return i;
	}
}
void get(int x)
{
	int t=find(x),s=1;
	for(int i=1;i<=phi[x];i++)
	{
		s*=t,s%=x;
		if(gcd(i,phi[x])==1) ans[++sum]=s;
	}
}

标签:lfloor,frac,数论,bmod,rfloor,初步,int,equiv
来源: https://www.cnblogs.com/zhs1/p/14397416.html

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

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

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

ICode9版权所有