P5431 【模板】乘法逆元2

HyperlinkHyperlinkHyperlink

https://www.luogu.org/problem/P5431


DescriptionDescriptionDescription

i=1nkiaimod p\sum_{i=1}^n\dfrac{k^i}{a_i}mod\ p∑i=1n​ai​ki​mod p

数据范围:n5×106,k&lt;p109,aipn\leq 5\times 10^6,k&lt;p\leq 10^9,a_i\leq pn≤5×106,k<p≤109,ai​≤p


SolutionSolutionSolution

求出aia_iai​的前缀积的逆元,倒序过来就得到所有的逆元

时间复杂度:O(n+logp)O(n+logp)O(n+logp)


CodeCodeCode

#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);
}
上一篇:杭电多校Day3 1006 Fansblog


下一篇:局部加权回归实例