质(素)数 : 任何数都能表示为质数的乘积,这应该是由质数的概念决定的,因为质数指:“质数(prime number)又称素数,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。” ,所以合数肯定等于质数*某数,而某数又可以用这样的规则拆分成质数的乘积!
另外有这样一个定理,如果a,x与n互质,则a*x与n互质!!! 因为a,x,n拆分成质数后,a,x与n拆分出来的质数是不同的,并且质数*质数并不会产生另外的质数,所以res=a*x的质数组成和n的质数组成是完全不同的,所以a*x与n互质~~~
乘法可取模证明:求a*b%m 设a=k1m+c1,b=k2m+c2 a*b=(k1m+c1)*(k2m+c2)=(k1k2+k1c2+k2c1)*m+c1c2=a%mod*(b%mod)
逆元:就把求 a (*1) /b%mod 时把1换成b^(φ(mod))==1 ,这样就能把分母约掉,然后化成乘法就可以先模后乘了!
求解逆元有三种方法 参考网址
线性时间内求范围内所有整数的逆元
当m不是很大的时候(数组能够存起来的时候)可以线性时间求逆元。规定m为质数,
首先 1^(−1) ≡ 1(mod m)
然后我们设 m = k*x + r, r < x, 1 < x < p;
再将这个式子放到mod m意义下就会得到
k*x + r ≡ 0 (mod m)
两边同时乘上 x^(−1) * r^(−1)就会得到
k * r^(−1) + x^(−1) ≡ 0 (mod m)
x^(−1) ≡ −k * r^(−1) (mod m)
x^(−1) ≡ -(m/x) * (m%x)^(−1) (mod m)
从头开始扫一遍即可,时间复杂度O(n);
int inv[maxn]; inv[1] = 1; for(int i = 2; i < maxn; ++i) inv[i] = (-p/i + p) * inv[p%i] % p;