洛谷 P5431 【模板】乘法逆元2 题解

假的模板题吧
题目传送门
题目大意:给定 n 个正整数 aip,k ,求

i1nkiai

答案对 p 取余数。
数据范围:
1n5×106
1k<p109
1ai<p

题目解析

其实这是一道 小 学 题 目
首先我们通分一下,分母当然是小学生做法,直接取 ai
不难得出:

i1nkiai=i=1n(ki×j=1i1aj×j=i+1naj)ai

显然预处理出数组 a 所有的前缀积和后缀积就好了。
记得除以 ai 的时候要用上逆元(不然怎么叫做逆元呢)
复杂度是 O(3n+log2p) 卡卡常数就可以了。

#include<cstdio>
#define maxn 5000039
using namespace std;
//#define debug
typedef long long ll;
typedef int Type;
inline Type read(){
Type sum=0;
int flag=0;
char c=getchar();
while((c<'0'||c>'9')&&c!='-') c=getchar();
if(c=='-') c=getchar(),flag=1;
while('0'<=c&&c<='9'){
sum=(sum<<1)+(sum<<3)+(c^48);
c=getchar();
}
if(flag) return -sum;
return sum;
}
int a[maxn],n;
ll head[maxn],tail[maxn],p,k;
ll getinv(ll x){
int y=p-2;
ll tmp=x,res=1;
while(y){
if(y&1) res=res*tmp%p;
y>>=1; tmp=tmp*tmp%p;
}
return res%p;
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=read(); p=read(); k=read();
for(int i=1;i<=n;i++)
a[i]=read();
head[0]=tail[n+1]=1;
for(int i=1;i<=n;i++) head[i]=head[i-1]*a[i]%p;
for(int i=n;i>=1;i--) tail[i]=tail[i+1]*a[i]%p;
ll res=0,tmp=k;
for(int i=1;i<=n;i++){
res=(res+tmp*head[i-1]%p*tail[i+1]%p)%p;
tmp=tmp*k%p;
}
printf("%lld",res*getinv(head[n])%p);
return 0;
}
posted @   jiangtaizhe001  阅读(94)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示