[洛谷P5431]【模板】乘法逆元2

题目大意:给定$n(n\leqslant5\times10^6)$个正整数$a_i$,和$k$。求:
$$
\sum_{i=1}^n\dfrac{k^i}{a_i}\pmod p
$$
题解:
$$
令P=\prod_{i=1}^na_i\pmod p\\
ans=\dfrac{\sum_{i=1}^nk^i\dfrac P{a_i}}{P}\pmod p\\
\dfrac P{a_i}可以前缀积后缀积解决
$$
卡点:

 

C++ Code:

#include <cstdio>
#include <cctype>
#include <algorithm>

namespace std {
	struct istream {
#define M (1 << 26 | 3)
		char buf[M], *ch = buf - 1;
		inline istream() { fread(buf, 1, M, stdin); }
		inline istream& operator >> (int &x) {
			while (isspace(*++ch));
			for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
			return *this;
		}
#undef M
	} cin;
	struct ostream {
#define M (1 << 10 | 3)
		char buf[M], *ch = buf - 1;
		inline ostream& operator << (int x) {
			if (!x) {*++ch = '0'; return *this;}
			static int S[20], *top; top = S;
			while (x) {*++top = x % 10 ^ 48; x /= 10;}
			for (; top != S; --top) *++ch = *top;
			return *this;
		}
		inline ostream& operator << (const char x) {*++ch = x; return *this;}
		inline ~ostream() { fwrite(buf, 1, ch - buf + 1, stdout); }
#undef M
	} cout;
}

#define maxn 5000010
#define mul(a, b) (static_cast<long long> (a) * (b) % mod)
int n, mod, k, pr = 1;
int a[maxn], sl[maxn], sr[maxn];

namespace Math {
	int pw(int base, int p) {
		static int res;
		for (res = 1; p; p >>= 1, base = mul(base, base)) if (p & 1) res = mul(res, base);
		return res;
	}
	int inv(int x) { return pw(x, mod - 2); }
}
inline void reduce(int &x) { x += x >> 31 & mod; }

int main() {
	std::cin >> n >> mod >> k;
	for (int i = 1; i <= n; ++i) {
		std::cin >> a[i];
		sl[i] = pr = mul(pr, a[i]);
	}
	pr = Math::inv(pr);
	sl[0] = sr[n + 1] = 1;
	for (int i = n; i; --i)
		sr[i] = mul(sr[i + 1], a[i]);
	int ans = 0, K = 1;
	for (int i = 1; i <= n; ++i) {
		K = mul(K, k);
		reduce(ans += mul(K, mul(sl[i - 1], sr[i + 1])) - mod);
	}
	ans = mul(ans, pr);
	std::cout << ans << '\n';
	return 0;
}

  

posted @ 2019-06-18 11:23  Memory_of_winter  阅读(283)  评论(0编辑  收藏  举报