😀因为exgcd一次是log2N,如果直接每个a【i】求逆时间复杂度为NlogN
所以优化成
😀因为s在计算中要%p,所以s/a[i]不一定是整数,所以又要用前缀积和后缀积来处理,即s/a[i]==pre[i-1]*suf[i+1]
😀这个题目中由于时间为0.55s<1s所以读入要手写,而且前缀积应该不要直接求一个含在过程里
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=5e6+10;

ll n,p,k,a[N],y,ans;
ll pre[N],suf[N],invs; 

ll read(){
	ll x=0,flag=1; char c;//函数变量一定要初始化,否则是随机数 
	while((c=getchar())<'0'||c>'9') if(c=='-') flag=-1;
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*flag;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
    if(!b){
        x=1; y=0;
        return a;
    }
    ll d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main(){
    n=read(); p=read(); k=read();
//    pre[0]=1;
    for(int i=1;i<=n;i++){
        a[i]=read();
//        pre[i]=pre[i-1]*a[i]%p;
    }
    suf[n+1]=1;
    for(int i=n;i>=1;i--){
    	suf[i]=suf[i+1]*a[i]%p;
	}
    exgcd(suf[1],p,invs,y);
    invs=(invs%p+p)%p;
	ll tmp=k;
    for(int i=1;i<=n;i++){
//      ans=(ans+tmp*infs%p*(pre[n]/a[i]))%p;//pre[n]计算时%p,s[n]/a[i]不一定能够整除 
//		ans=(ans+tmp*invs%p*pre[i-1]%p*suf[i+1]%p)%p;//前缀积含在过程里,不单独求 
		ans=(ans+tmp*invs%p*suf[i+1])%p;
		invs=invs*a[i]%p;
        tmp=tmp*k%p;
    }
    printf("%lld",ans);
    return 0;
}