1. 程式人生 > 其它 >P5431 【模板】乘法逆元2

P5431 【模板】乘法逆元2

技術標籤:題解

P5431 【模板】乘法逆元2

題意:

在這裡插入圖片描述

Solution:

這題主要是學一個想法。
s i = a 1 ∗ a 2 ∗ . . . ∗ a i 1 s i = 1 a 1 ∗ a 2 ∗ . . . ∗ a i 1 s i − 1 = 1 s i ∗ a i 1 a i = s i − 1 s i s_i=a_1*a_2*...*a_i \\ \frac{1}{s_i}=\frac{1}{a_1*a_2*...*a_i} \\ \frac{1}{s_{i-1}}=\frac{1}{s_i}*a_i \\ \frac{1}{a_i}=\frac{s_{i-1}}{s_i}

si=a1a2...aisi1=a1a2...ai1si11=si1aiai1=sisi1
因此對於此題,只要先求出 s n − 1 s_n^{-1} sn1,然後逆推出 s i − 1 s_i^{-1} si1,和對應 a i − 1 a_i^{-1} ai1

程式碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
char ch;
void read(int &x){
	x=
0; for(ch=getchar();ch<'0'||ch>'9';ch=getchar()); for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch&15); } int n,p,k; int a[5000005]; int ext_gcd(int a,int b,int &x,int &y) { if(b==0) { x=1;y=0; return a; } int d=ext_gcd(b,a%
b,x,y); int tem=y; y=x-a/b*y; x=tem; return d; } int inv(int a,int b) { int x,y; int d=ext_gcd(a,b,x,y); x=(x%p+p)%p; return x; } int Inv[5000005],b[5000005]; int main() { read(n);read(p);read(k); int qaq=1; for(int i=0;i<n;i++) { read(a[i]); if(i==0)b[i]=a[i]; else b[i]=1ll*b[i-1]*a[i]%p; } qaq=inv(b[n-1],p); for(int i=n-1;i>=0;i--) { if(i==0){Inv[i]=qaq;break;} Inv[i]=1ll*qaq*b[i-1]%p; qaq=1ll*qaq*a[i]%p; } int res=0; int q=1; for(int i=0;i<n;i++) { q=1ll*q*k%p; res=1ll*(res+1ll*Inv[i]*q%p)%p; } printf("%d",res); return 0; }