数学

2020年01月27日18:36:47

  1. 费马小定理
  2. 扩展欧几里得算法
  3. 欧拉函数
  4. 扩展( extrm {CRT})
  5. ( extrm{Lucas})定理
  6. 扩展( extrm{Lucas})
  7. ( extrm{BSGS})
  8. ( extrm{EX-BSGS})
  9. ( extrm{Miller-Rabin&Pollard-Rho})
  10. 拉格朗日插值
  11. 高斯消元
  12. 欧拉定理

欧几里得算法

费马小定理

定理:((p) 为质数,(p mid a))

[ a^{p-1}equiv1mod p ]

证明:(学习链接

设一个质数为(p),我们取一个不为(p)倍数的数(a)

构造一个序列:(A={1,2,3dots,n-1})

[ Pispace A_i=Pi (A_i imes a) mod p ]

解释:

[ ecause (A_i,p)=1,(A_i imes a,p)=1\ 又 ecause 每一个A_i imes a mod p 都是独一无二的,且A_i imes a mod p < p \ 得证 ]

(f=(p-1)!),

(fequiv a imes A_1 imes a imes A_2 imes a imes A_3 dots imes A_{p-1} (mod p))

[ a^{p-1} imes f equiv f mod p \ a^{p-1} equiv 1 mod p ]

例题:乘法逆元
设逆元为(x)

[ ecause a*xequiv 1 mod p ,a^{p-1}equiv 1 mod p \ herefore a^{p-2}equiv x mod p ]

例题2:有理数取余

除以一个数等于乘那个数的倒数
逆元有'同余倒数'之称

数据过大只需要边读入边%即可。

例题3:乘法逆元2

考虑到逆元的性质。题目实际上要我们求(largefrac{1}{a_i} mod p),我们只需要构造出求出(largefrac{1}{a_i})而不用除法的方式。

[ 设space extsf S_jspace=Pi_{i=1}^{ile j} \ frac{1}{a_i}=frac{1}{S_i} imes S_{i-1} \ frac{1}{S_i}=frac{1}{S_{i+1}} imes a_i ]

一开始的(frac{1}{S_{i+1}})用逆元算即可。
代码

const int N = 6000001;
int A[N],S[N],Inv[N];
int mod;
inline int Pow(int b,int p)
{
	int ans=1;
	while(p)
	{
		if(p&1)
		{
			ans*=b;
			ans%=mod;
		}
		b*=b;b%=mod;
		p>>=1;
	}
	return ans;
}
signed main()
{
	#ifndef ONLINE_JUDGE
		freopen("data.in","r",stdin);
	#endif
	int n,k;
	in3(n,mod,k);
	S[0]=1;
	for(int i=1;i<=n;++i) 
	{
		in(A[i]);
		S[i]=A[i]*S[i-1];
		S[i]%=mod;
	}
	Inv[n]=Pow(S[n],mod-2);
	int tmp=1,ans=0;
	for(int i=n-1;i>=1;--i)
		Inv[i]=(Inv[i+1]*A[i+1])%mod;
	for(int i=1;i<=n;++i)
	{
		int iv=(Inv[i]*S[i-1])%mod;
		tmp*=k;tmp%=mod;
		int qwq=(tmp*Inv[i])%mod;
		ans=(ans+(qwq*S[i-1])%mod)%mod;
	}
	write(ans);
	return 0;
}

扩展欧几里得算法

欧几里得算法:

int gcd(int a,int b)
{
	if(!b) return a;
	return gcd(b,a%b);
}

算法解决这样一个不等方程:

[ ax+by=c  且c满足 c|(a,b) ]

于是乎,我们可以利用这个方程求逆元:

[ a imes x equiv 1 mod b \ ax-by= 1 ]

我们也可以理解成:

[ ax+by=1 (y le 0) ]

假设我们已经求出了一组解:(x_1,y_1)

[ ecause ax+by=gcd(a,b)=gcd(b,amod b) \ herefore ax+by=bx_1+(amod b)y_1 \ Rightarrow ax+by=bx_1+a imes y_1-lfloor frac{a}{b} floor imes b imes y_1 \ =ay_1+b(x_1-lfloorfrac{a}{b} floor imes y_1) \ herefore x=y_1,y=x_1-lfloorfrac{a}{b} floor imes y_1 ]

代码:

void Exgcd(int a,int b,int &x,int &y)
{
	if(!b) {x=1,y=0;return;} // b必然会等于0,这个时候ax+by=gcd(a,b),还要成立
	Exgcd(b,a%b,y,x),y-=a/b*x;
}

例题:
设飞行次数为(a)

[ ad+xequiv y mod n \ ad+x=y-bn \ ad+bn=y-x ]

用扩展欧几里得求出(a,(b))即可。

一些细节:
在求解(ax+by=c)时,我们通常采用以下方法:

[ 1. 将等式两边同时除以(a,b) \ 2. 将问题化为ax+by=1,求出答案后在乘上c\ 解系:\ din mathbb{Z}\ egin{cases} x = x + db \ y = y - da \ end{cases} ]

所以标程如下:

void  Exgcd(int a,int b,int &x,int &y)
{
	if(!b) {x=1,y=0;return;}
	Exgcd(b,a%b,y,x);y-=a/b*x;
}
signed main()
{
	int T=gi();
	while(T--)
	{
		int n,d,x,y;
		in4(n,d,x,y);
		int a=0,b=0;
		int gcd=__gcd(d,n);
		if((y-x)%gcd)
		{
			puts("Impossible");
			continue;
		}
		Exgcd(d,n,a,b);
		a*=(y-x);a/=gcd;
		n/=gcd;
		// write2(a,b);
		a=((a%n)+n)%n;
		write(a);line();
	}
}

( extrm{EXCRT})

[left{ egin{aligned} x_1equiv b_1mod m_1 \ x_2equiv b_2mod m_2 \ x_3equiv b_3mod m_3 \ .................\ x_iequiv b_imod m_i \ end{aligned} ight. ]

对于这样一组关于x的同余方程,我们需要求出其中的最小整数解,m之间不保证互质,我们就需要用到扩展中国剩余定理。(证明思路参考)

假设我们已经求出了我们已经求出了前 (i) 组方程的一个解,我们称之为(X),前(i)(m)(lcm)为M。根据扩展欧几里得的解系可以得出:(X+k imes M(kin mathbb{Z}))

[X+t imes Mequiv b_i mod m_i Rightarrow X+t imes M =b_i-q imes m_i \t imes M+q imes m_i=b_i-X \两边同时除以gcd(M,m_i),变成\ax+by=c\ 的形式 ]

( extrm{BSGS})

[a^xequiv bmod p \ 设 x =Alceilsqrt{p} ceil-B:\ a^{Alceilsqrt{p} ceil-B}equiv bmod p \ a^{Alceilsqrt p ceil}equiv a^Bb mod p ]

枚举(A,B)即可。

原文地址:https://www.cnblogs.com/guodongLovesOi/p/12238684.html