【数论】乘法逆元【CF】I. Prefix Prizes
乘法逆元
引入
\((a+b)\%p=(a\%p+b\%p)\%p\)
\((a-b)\%p=(a\%p-b\%p)\%p\)
\((a\times b)\%p=(a\%p\times b\%p)\%p\)
令\(a=k_1p+m_1,b=k_2p+m_2\)
易证以上三个性质
但\((a/ b)\%p=(a\%p/b\%p)\%p\)这个性质是不成立的
因而数学家引入乘法逆元这个性质用来解决这个问题
定义
在mod p意义下,对于一个数a,存在一个数x,使得\(a\times x\equiv1(mod \space p)\),那么则称整数x和a互为乘法逆元。
[充要条件]a存在模p的乘法逆元的充要条件是gcd(a,p)=1,即a与p互质。
应用
当求(a/b)%p时,可将其转换为a*(b的逆元)%p
证明
令b的逆元为x
$(a/b)%p=m\Rightarrow (a/b)%p=m%p\Rightarrow(a/b)%p\times(b%p)=m%p\times(b%p) $
\(\Rightarrow a\%p=(m\times b)\%p\Rightarrow a\%p\times x\%p=(m\times b)\%p\times x\%p\)
\(=m\%p\times (b\times x)\% p=m\%p\)
\(\Rightarrow (a\times x)\%p=m\%p\)
即\(\Rightarrow (a\times x)\%p=m\)
因而可使得原本不能用的性质,转化为可以使用的性质。
\((a\times b)\%p=(a\%p\times b\%p)\%p\)
逆元的求法
方法一:借助费马小定理
对于任意存在的整数a和p,有gcd(a,p)=1,且p为质数,则有\(a^{p-1}\%p=1\)
于是\((a^{p-2}\times a)\% p=1\),其中\(a^{p-2}\)为a的逆元,且可借助快速幂算法来求出。
快速幂
int qpow(int a,int n)
{
int ans = 1;
while(n)
{
if(n&1)
ans *= a;
a *= a;
n >>= 1
}
return ans;
}
此题易知首项为1,末项为n
尝试去构造一个数列1,2,3,4,5,...,n-1,n。
前一项余数为x,后一项余数为x+1。
有\((x\times m)\%p=x+1\Rightarrow m\%p=(x+1)\times x^{-1}\Rightarrow m=(x+1)\times x^{-1}\)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool isprime(int x)
{
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
return false;
}
return true;
}
ll mod;
ll qmi(ll base,ll n)
{
ll ans=1;
while(n)
{
if(n&1)ans=ans*base%mod;
base=base*base%mod;
n>>=1;
}
return ans;
}
int main()
{
int n;
cin>>n;
mod=n;
if(n<=3)
{
for(int i=1;i<=n;i++)
{
if(i!=1) cout<<" ";
cout<<i;
}
}
else if(n==4)
cout<<"1 3 2 4";
else if(isprime(n))
{
ll x=1;
cout<<1;
for(int i=2;i<=n-1;i++)
{
ll t=qmi(x,n-2)*(x+1)%mod;
cout<<" "<<t;
x++;
}
cout<<" "<<n;
}
else cout<<"-1";
return 0;
}