Hyperlink
https://www.luogu.org/problem/P5431
Description
求∑i=1naikimod p
数据范围:n≤5×106,k<p≤109,ai≤p
Solution
求出ai的前缀积的逆元,倒序过来就得到所有的逆元
时间复杂度:O(n+logp)
Code
#include<cstdio>
#include<cctype>
#define LL long long
using namespace std;
#define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<15,stdin),S==T)?EOF:*S++)
char BB[1<<15],*S=BB,*T=BB;//木有介两行你可能会T飞
LL n,mod,k,s[5000010],inv[5000010],a[5000010],ans;
inline LL read()
{
LL f=0,d=1;char c;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
LL ksm(LL x,LL y)
{
LL ans=1;
for(;y;(x*=x)%=mod,y>>=1) if(y&1) (ans*=x)%=mod;
return ans;
}
signed main()
{
n=read();mod=read();k=read();
inv[n+1]=1;s[0]=1;
for(register int i=1;i<=n;i++) a[i]=read(),s[i]=s[i-1]*a[i]%mod;
inv[n+1]=ksm(s[n],mod-2);
for(register int i=n;i>0;i--) inv[i]=inv[i+1]*a[i]%mod;
LL kf=k;
for(register int i=1;i<=n;i++)
{
ans=(ans+(inv[i+1]*s[i-1]%mod)*kf%mod)%mod;
(kf*=k)%=mod;
}
printf("%lld\n",ans);
}