刚学莫反求助,又红又紫
查看原帖
刚学莫反求助,又红又紫
118196
zimujun楼主2021/3/17 22:11

RT

过了样例,检查数据范围(大概)没出问题,结果交上去又是 WA 又是 RE 的

记录

推导过程在这里

代码中做了一些注释,应该还能看(

#include <bits/stdc++.h>

#define LL long long

using namespace std;
 
namespace I {
	template <typename Temp> inline void read(Temp & res) {
		Temp fh = 1; res = 0; char ch = getchar();
		for(; !isdigit(ch); ch = getchar()) if(ch == '-') fh = -1;
		for(; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ '0');
		res = res * fh;
	}
}
 
const int Maxn = 1e5 + 5;

int T, n, A, B, C; LL Mod = 1;

namespace M {
	#define N 100000
	inline LL qpow(LL a_qp, LL p_qp) {
		LL res = 1;
		while(p_qp) {
			if(p_qp & 1) res = res * a_qp % Mod;
			a_qp = a_qp * a_qp % Mod;
			p_qp >>= 1; 
		}
		return res;
	}
	
	int prime[Maxn], cnt_pri; LL phi[Maxn], mu[Maxn]; bool isprime[Maxn];
	void sieve() {
		phi[1] = mu[1] = 1;
		for(int i = 2; i <= N; ++i) {
			if(!isprime[i]) {
				prime[++cnt_pri] = i;
				phi[i] = i - 1; mu[i] = -1;
			}
			for(int j = 1; j <= cnt_pri && prime[j] <= N / i; ++j) {
				int cur = i * prime[j];
				isprime[cur] = 1;
				if(i % prime[j] == 0) {
					phi[cur] = phi[i] * prime[j];
					mu[cur] = 0; break;
				} else {
					phi[cur] = phi[i] * (prime[j] - 1);
					mu[cur] = -mu[i]; 
				}
			}
		} 
	}
	
	LL fac[Maxn], invf[Maxn], inv[Maxn];
	void getinv() {
		fac[0] = 1; inv[0] = 1;
		for(int i = 1; i <= N; ++i) fac[i] = 1ll * fac[i - 1] * i % Mod;
		invf[N] = qpow(fac[N], Mod - 2);
		for(int i = N - 1; i >= 0; --i) invf[i] = 1ll * invf[i + 1] * (i + 1) % Mod;
		for(int i = 1; i <= N; ++i) inv[i] = invf[i] * fac[i - 1] % Mod; 
	}
	
	LL s(int n_s) {
		return 1ll * n_s * (n_s + 1) / 2 % (Mod - 1);
	}
	
	LL sphi[Maxn]/*Mod by (p - 1)*/, f[Maxn], ftp[Maxn], ip[Maxn], fip[Maxn];/*prod d^mu(T/d), i^i and its prefix*/
	LL ffac[Maxn], ftpfac[Maxn], finvf[Maxn], ftpinvf[Maxn], finv[Maxn], ftpinv[Maxn];
	//fac of f, fac of f^(T^2), fac_inv of f, fac_inv of f^(T^2), inv of f, inv of f^(T^2)
	void Init() {
		sieve(); getinv(); fip[0] = 1; finv[0] = ftpinv[0] = 1;
		for(int i = 1; i <= N; ++i) ip[i] = qpow((LL)i, (LL)i), fip[i] = fip[i - 1] * ip[i] % Mod;
		for(int i = 1; i <= N; ++i) sphi[i] = (sphi[i - 1] + phi[i]) % (Mod - 1);
		for(int i = 1; i <= N; ++i) f[i] = 1;
		for(int d = 1; d <= N; ++d) {
			for(int t = 1; t <= N / d; ++t) {
				if(mu[t] == -1) f[d * t] = f[d * t] * inv[d] % Mod;
				else if(mu[t] == 1) f[d * t] = f[d * t] * d % Mod; 
			}
		}
		for(int i = 1; i <= N; ++i) ftp[i] = qpow(f[i], 1ll * i * i % (Mod - 1)) % Mod;
		ffac[0] = ftpfac[0] = 1;
		for(int i = 1; i <= N; ++i) ffac[i] = ffac[i - 1] * f[i] % Mod,
		ftpfac[i] = ftpfac[i - 1] * ftp[i] % Mod;
		finvf[N] = qpow(ffac[N], Mod - 2); ftpinvf[N] = qpow(ftpfac[N], Mod - 2);
		for(int i = N - 1; i >= 0; --i) finvf[i] = finvf[i + 1] * f[i + 1] % Mod,
		ftpinvf[i] = ftpinvf[i + 1] * ftp[i + 1] % Mod;
		for(int i = 1; i <= N; ++i) finv[i] = finvf[i] * ffac[i - 1] % Mod,
		ftpinv[i] = ftpinvf[i] * ftpfac[i - 1] % Mod;
	}
	#undef N
}

namespace ANS {
	using namespace M;
	LL A1(int a, int b, int c) {
		return qpow(fac[a], 1ll * b * c % (Mod - 1));
	}
	LL A2(int a, int b, int c) {
		LL res = 1;
		if(a > b) swap(a, b);
		for(int l = 1, r = 1; l <= a; l = r + 1) {
			r = min(a / (a / l), b / (b / l)); r = min(r, a);
			res = res * qpow(ffac[r] * finvf[l - 1] % Mod, 1ll * (a / l) * (b / l) % (Mod - 1));
		}
		return qpow(res, (LL)c);
	}
	LL B1(int a, int b, int c) {
		return qpow(fip[a], s(b) * s(c) % (Mod - 1));
	}
	LL B2(int a, int b, int c) {
		LL res = 1;
		if(a > b) swap(a, b);
		for(int l = 1, r = 1; l <= a; l = r + 1) {
			r = min(a / (a / l), b / (b / l)); r = min(r, a);
			res = res * qpow(ftpfac[r] * ftpinvf[l - 1] % Mod, s(a / l) * s(b / l) % (Mod - 1)) % Mod;
		}
		return qpow(res, s(c));
	}
	LL C1(int a, int b, int c) {
		LL res = 1;
		for(int l = 1, r = 1; l <= a; l = r + 1) {
			r = min(a / (a / l), min(b / (b / l), c / (c / l)));
			LL cur = qpow(fac[a / l], 1ll * (b / l) * (c / l) % (Mod - 1));
			res = res * qpow(cur, ((sphi[r] - sphi[l - 1]) % (Mod - 1) + (Mod - 1)) % (Mod - 1)); 
		}
		return res;
	}
	LL C2_0(int a, int b) {
		LL res = 1;
  	for (int l = 1, r = 1; l <= min(a, b); l = r + 1) {
    	r = min(a / (a / l), b / (b / l));
    	res = res * qpow(ffac[r] * finvf[l - 1], 1ll * (a / l) * (b / l) % (Mod - 1)) % Mod;
  	}
  	return res;
	} 
	LL C2(int a, int b, int c) {
		int m = min(a, min(b, c)); LL res = 1;
		for(int l = 1, r = 1; l <= m; l = r + 1) {
			r = min(a / (a / l), min(b / (b / l), c / (c / l)));
			LL cur = qpow(C2_0(a / l, b / l), 1ll * (c / l));
			res = res * qpow(cur, ((sphi[r] - sphi[l - 1]) % (Mod - 1) + (Mod - 1)) % (Mod - 1)) % Mod;
		}
		return res;
	}
	LL Solve(int a, int b, int c, int type) {//abc bac abc acb
		if(type == 0) {
			return 1ll * A1(a, b, c) * A1(b, a, c) % Mod * qpow(A2(a, b, c) * A2(a, c, b) % Mod, Mod - 2) % Mod;
		} else if(type == 1) {
			return 1ll * B1(a, b, c) * B1(b, a, c) % Mod * qpow(B2(a, b, c) * B2(a, c, b) % Mod, Mod - 2) % Mod;
		} else {
			return 1ll * C1(a, b, c) * C1(b, a, c) % Mod * qpow(C2(a, b, c) * C2(a, c, b) % Mod, Mod - 2) % Mod;
		}
	}
}

int main() {
	using namespace I;
	read(T); read(Mod); M::Init();
	while(T--) {
		read(A); read(B); read(C);
		for(int i = 0; i <= 2; ++i) printf("%lld ", ANS::Solve(A, B, C, i));
		printf("\n");
	}
	return 0;
}
2021/3/17 22:11
加载中...