Basically written copy of the god of things, mainly as a refresher, a deeper impression.
Definition: If the integer b, m coprime, and b | a (b divisible A), there is an integer x, such that A / B A * C ≡ (MOD m) . Called modulo m b x of multiplying method inverse element, referred to as B -1 (MOD m) .
So how do we seek b -1 (MOD m) ?
By definition, A / B * B A ≡ -1 ≡ A / B * B * B -1 ( MOD m ), then B * B -1 ≡. 1 (MOD m).
Here can be solved in two ways B -1 (MOD m) :
1, Fermat's little theorem.
Fermat's Little Theorem: If p is a prime number, then for any integer a, there are A p ≡ A (MOD p). Then B P ≡ B (MOD P) B → B * P. 1- ≡ B (MOD P) B → B * P-2 ≡. 1 (P MOD). Thus, when the modulo a prime number p , B p-2 is the B -1 (MOD p) . So we can use to quickly find inverse power.
int qpow(int i,int k,int mod) { int res=1; while(k) { if(k&1) res=(LL)res*i%mod; i=(LL)i*i%mod; k>>=1; } return res; } int main() { int invb=qpow(b,p-2,p); //p是质数,b的逆元就是b^(p-2) mod p return 0; }
2, the solution congruence equation.
Since B * B -1 ≡. 1 (MOD m), then the solution congruence equation b * x ≡ 1 (mod m ) is an inverse element, equivalent to solving equation b * x + m * y = 1, according to the extended Euclidean Reed, as long as the b, m coprime, we can find the inverse element in this way.
void exgcd(int a,int b,int &x,int &y) { if(b==0) {x=1;y=0;return;} exgcd(b,a%b,x,y); int z=x;x=y;y=z-a/b*y; } int main() { int x,y; exgcd(b,p,x,y); x=(x%p+p)%p; return 0; }
Of course, there are other special circumstances we need to use a special method to find the inverse element:
1, solving the inverse 1 ~ n this series of consecutive numbers:
Known. 1 -1 ≡. 1 (P MOD)
Provided p = k * i + r, i.e. ⌊p / i⌋ = k, p% i = r
Then k * i + r ≡ 0 (mod p)
Is multiplied with the left and right I -1 R & lt -1 , to give R & lt * K -1 + I -1 ≡ 0 (P MOD)
Transposition to give I -1 ≡ -k * R & lt -1 (P MOD)
Since k = ⌊p / i⌋, r = p% i
Available, I -1 = -⌊p / i⌋ * (% P I) -1 (P MOD)
To ensure the inverse is positive, so
i-1 = (p-⌊p/i⌋) * (p%i)-1 (mod p)
Then we can use this formula to launch delivery of inverse 1 ~ n.
int main() { scanf("%d%d",&n,&p); inv[1]=1; for(int i=2;i<=n;i++) inv[i]=(LL)(p-p/i)*inv[p%i]%p; for(int i=1;i<=n;i++) printf("%d\n",inv[i]); return 0; }
2, the inverse element 1 to n factorial of the number of :
因为$\dfrac {1}{\left( i+1\right) !}\times \left( i+1\right) =\dfrac {1}{i!}$
Provided inv [i] is I! Inverse element, then inv [i + 1] * (i + 1) = inv [i]
Using this relationship we can know in case inv [n] inverse launch 1 ~ n factorial of the inverse.
int qpow(int i,int k,int mod) { int res=1; while(k) { if(k&1) res=(LL)res*i%mod; i=(LL)i*i%mod; k>>=1; } return res; } int main() { scanf("%d%d",&n,&p); fact[0]=1; for(int i=1;i<=n;i++) fact[i]=(LL)fact[i-1]*i%p; invi[n]=qpow(fact[n],p-2,p); for(int i=n-1;i>=1;i--) invi[i]=(LL)invi[i+1]*(i+1)%p; return 0; }