## luogu problem solution P3811 [[template] multiplication inverse element]

https://www.luogu.org/problemnew/show/P3811

• concept:

When I think of the JXOI 2018 exam room, I forgot how to fight Ni Yuan.

We may often encounter such a situation (such as JXOI2018 T1)

To calculate a formula similar to $$a/b$$ % $$p$$ , according to the congruence property, we cannot calculate it like this: $a \mod p /b \mod p$

But if it is in the ordinary formula, obviously $$a/b$$ = $$a*b^-1$$ .

In the sense of $$\pmod p$$ , we might as well construct a $$b^-1$$ such that $$b*b^-1 \equiv 1 \pmod{p}$$ ;

Then $$a/b \pmod p \equiv a*b^-1 \pmod p$$ , for the first question, we can safely take $$a$$ % $$p$$ , then multiply by \ (b\) The inverse element in the sense of $$\pmod p$$ is too convenient

This leads to the definition of the inverse element:

If $$b*x \equiv 1 \pmod{p}$$ and $$b, p$$ are relatively prime, then $$x$$ is $$b$$ in the sense of $$\pmod p$$ Inverse element, denoted as $$b^-1$$

• Ideas:

There are generally three algorithms for calculating the inverse

• Extended Euclid

According to the definition, if the inverse of $$b$$ in the sense of $$\pmod p$$ is required, it is to find the x in $$b*x \equiv 1 \pmod{p}$$ and convert it into a linear congruence Equation $$b*x+p*y=1$$ , then just run it with Tuoou

• Fermat's little theorem

If p is a prime number, then for any positive integer b, there is $$b^{p} \equiv b \pmod{p}$$

So $$b^{p-1} \equiv 1 \pmod{p}$$ continue to split b to get

$$b*b^{p-2} \equiv 1 \pmod{p}$$

Comparing with the above definition of inverse element, we only need to find $$b^{p-2} \pmod p$$

• Linear recurrence

$$p=k*i+r$$ 所以$$k=\left \lfloor \frac{p}{i} \right \rfloor,r=p \mod i$$

So $$k*i+r \equiv 0 \pmod p$$ is also multiplied by $$i^-1,r^-1$$

$$k*r^-1+i^-1 \equiv 0 \pmod p$$ Shift term

$$i^-1 \equiv -k*r^-1 \pmod p$$

$$i^-1 \equiv -\left \lfloor \frac{p}{i} \right \rfloor*{(p \mod i)}^-1\pmod p$$

We store all inverses in the inv[] array, then

inv[i]=-((p/i)*inv[p%i]%p); while(inv[i]<0)inv[i]+=p;
Of course inv[1]=1;

• Code:

• Tuoou + Fermat's little theorem

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL mod(LL a,LL b)
{
if(a<b)return a;
if(a==b)return 0;
else return a-a/b*b;
}
LL pow_mod(LL a, LL b, LL p){//a的b次方求余p
LL ret = 1;
while(b){
if(b & 1) ret = mod((ret * a) ,p);
a =mod((a * a) ,p);
b >>= 1;
}
return ret;
}
LL Fermat(LL a, LL p){//费马求a关于b的逆元
return pow_mod(a, p-2, p);
}
void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
if (!b) {d = a, x = 1, y = 0;}
else{
ex_gcd(b, mod(a,b), y, x, d);
y -= x * (a / b);
}
}
LL inv(LL t, LL p){//如果不存在，返回-1
LL d, x, y;
ex_gcd(t, p, x, y, d);
return d == 1 ? (mod(x,p) + p) % p : -1;
}
int main()
{
int op;
LL a,p;
cin>>a>>p;
for(int i=1;i<=a;i++)cout<<inv(i,p)<<endl;
return 0;
}
• Linear recurrence
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <cmath>
#deinfe ll long long
using namespace std;
const int maxn=3000005;
int n,p;
ll inv[maxn];
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;
return ;
}
inline void make_inv(){
printf("1\n");   //inv[1];
for(register int i=2;i<=n;i++){
inv[i]=-((p/i)*inv[p%i]%p);
while(inv[i]<0)inv[i]+=p;
printf("%lld\n",inv[i]);
}
return ;
}
int main()
{
}