[题解]P5431 【模板】模意义下的乘法逆元 2
可恶,卡常好难受。
将分数通分,第\(i\)个分数是\(\frac{k^i*fac\div a[i]}{fac}\),\(fac\)表示所有元素的积。
我们可以用\(lr,rl\)记录\(a\)的前缀后缀积,第\(i\)个分数就是\(\frac{k^i*lr[i-1]*rl[i+1]}{lr[n]}\)。这样分母都是\(lr[n]\),分子就是上面一串的和。
然后用一遍逆元求出答案即可,这里用费马小定理。
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,p,k,a[5000010];
int lr[5000010],rl[5000010];
int read(){
int x=0,w=1;
char ch=0;
while(ch<'0'||ch>'9'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
return x*w;
}
int qp(int a,int b){
int ans=1;
while(b){
if(b&1) ans=(ans*a)%p;
a=a*a%p;
b>>=1;
}
return ans;
}
signed main(){
n=read(),p=read(),k=read();
lr[0]=1,rl[n+1]=1;
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) lr[i]=lr[i-1]*a[i]%p;
for(int i=n;i>=1;i--) rl[i]=rl[i+1]*a[i]%p;
int frac1=0,frac2=lr[n],t=k;
for(int i=1;i<=n;i++){
frac1=(frac1+lr[i-1]*rl[i+1]%p*t%p)%p;
t=(t*k)%p;
}
cout<<frac1*qp(frac2,p-2)%p;
return 0;
}