P5431 模意义下的乘法逆元
思路
求前缀积,然后求第\(n\) 个数的逆元
\(sv[i - 1] = sv[i] * a[i]\)最后在根据 \(inv[i] = prefix[i - 1] * sv[i]\) 即可。
代码
#include <bits/stdc++.h>
using i64 = long long;
const int N = 5e6 + 10;
int n, p, k, arr[N], prefix[N], sv[N], K[N];
int fast_pow(int a, int b, int mod) {
int res = 1;
while (b) {
if (b & 1) res = (i64) res * a % mod;
a = (i64) a * a % mod;
b >>= 1;
}
return res;
}
template<class T>
T read(T &x){
x=0;char ch=0;
while(ch < '0' || ch > '9')ch=getchar();
while(ch >= '0' && ch <= '9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
int main() {
read(n), read(p), read(k);
prefix[0] = K[0] = 1;
for (int i = 1; i <= n; i ++) {
read(arr[i]);
prefix[i] = (i64) arr[i] * prefix[i - 1] % p;
K[i] = (i64) K[i - 1] * k % p;
}
sv[n] = fast_pow(prefix[n], p - 2, p);
i64 res = 0;
for (int i = n; i >= 1; i --) {
sv[i - 1] = (i64) sv[i] * arr[i] % p;
res += (((i64) sv[i] * prefix[i - 1] % p) * K[i])% p;
res %= p;
}
printf("%lld", res);
}