求1-n全部整數在模p意義下的逆元。c++
若是x知足\(ax=1(\%p)\)(其中a p是給定的數)那麼稱\(x\)是在\(%p\)意義下\(a\)的逆元算法
\[ax=1(\%p)\]
轉換一下也就是
\[ax+py=1\]函數
#include<bits/stdc++.h> using namespace std; typedef long long ll; int extgcd(int a,int b,int&x,int&y){ if(b==0){ x=1; y=0; return a; } int g=extgcd(b,a%b,y,x); y-=a/b*x; return g; } int main(){ int a,b,x,y; cin>>a>>b; for(int i=1;i<=a;i++){ extgcd(i,b,x,y); cout<<(x%b+b)%b<<endl; } }
得分:48。TLEspa
當p是質數時:
\[a^{p-1}≡1(\%p)\]
將其變形一下即得
\[a*a^{p-2}≡1(\%p)\]code
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll qpow(ll a,ll b,ll p){ ll ans=1; while(b){ if(b%2){ ans*=a; ans%=p; } a*=a; a%=p; b>>=1; } return ans%p; } int main(){ int n,p; cin>>n>>p; for(int i=1;i<=n;i++){ cout<<(qpow(i,p-2,p)%p+p)%p<<endl; } }
得分:48。TLEip
費馬小定理只是歐拉定理的特殊狀況。歐拉定理:
\[a^{\phi(p)}=1(\%p)\]
也就是說\(a^{\phi(p)-1}\)是\(a\)在\(\%p\)意義下的逆元。
其中\(\phi\)是歐拉函數:小於n的正整數中與n互質的數的數目。
通式:\(\phi(n)=n\Pi_{i=1}^{n}\left(1-\frac{1}{p_i}\right)\)
遞推性質:ci
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll qpow(ll a,ll b,ll p){ ll ans=1; while(b){ if(b%2){ ans*=a; ans%=p; } a*=a; a%=p; b>>=1; } return ans%p; } ll n,p; ll phi[20000529],prime[2000052],ps; bool mark[2000052]; void calc(){ phi[1]=1; for(int i=2;i<=p;i++){ if(!mark[i]){ prime[++ps]=i; phi[i]=i-1; } for(int j=1;j<=ps;j++){ if(i*prime[j]>p)break; mark[i*prime[j]]=1; if(i%prime[j]==0){ phi[i*prime[j]]=phi[i]*prime[j]; break; }else{ phi[i*prime[j]]=phi[i]*(prime[j]-1); } } } } int main(){ cin>>n>>p; calc(); for(int i=1;i<=n;i++){ cout<<(qpow(i,phi[p]-1,p)%p+p)%p<<endl; } }
得分:32。TLEget
設
\[p=ka+r\]
而後放到\(\%p\)意義下
\[ka+r=0(\%p)\]
兩邊同時乘以\(a^{-1}r^{-1}\)
\[kr^{-1}+a^{-1}=0(\%p)\]
因此
\[a^{-1}=-kr^{-1}=-\left[\frac{p}{a}\right]*(p\%a)^{-1}\]
轉換成代碼就是it
inv[a]=-(p/a)*inv[p%a];
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,p; int inv[3000000]; int main(){ scanf("%d%d",&n,&p); inv[1]=1; printf("1\n"); for(int i=2;i<=n;i++){ inv[i]=((-((ll)p/i)*inv[p%i])%p+p)%p; printf("%d\n",inv[i]); } }