/youl 乐团 题解

P5518 [MtOI2019]幽灵乐团 / 莫比乌斯反演基础练习题

以下 \(/\) 表示下取整除法(时间复杂度除外),分数线才是真正的除法。

以下时间复杂度中的 \(n\) 表示 \(\max(A,B,C)\)

对于不平常的柿子推导顺序,深感抱歉。

冗长の前置

0

注意别将 \(\sum\)\(\prod\) 搞混,并且清楚他们的基础变换。

1

明白这个转换(\(f\) 为任意函数):

\[\begin{aligned} \sum_{i=1}^{A}\sum_{j=1}^{B}\sum_{k=1}^{C}\gcd(i,j,k)f(i,j,k) &=\sum_{i=1}^{A}\sum_{j=1}^{B}\sum_{k=1}^{C}f(i,j,k)\sum_{d|i\ d|j\ d|k}\varphi(d) \\ &=\sum_{d=1}^{\min(A,B,C)}\varphi(d)\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}\sum_{k=1}^{C/d}f(di,dj,dk) \end{aligned} \]

2

今天的 mvp 是(因为等会儿会用得多,先写上来):

\[mvp(n)=\sum_{d|n}d^{\mu(\frac{n}{d})} \]

(没错起名就是这么随意)

她的前缀积预处理配合上整除分块可以 \(O(\sqrt n\log n)\) 解决这个问题(由对称性,不妨设 \(A\le B\);幂太长了,用 \(\text{pow}\) 代替):

\[\begin{aligned} F(A,B)&=\prod_{i=1}^A\prod_{j=1}^B\gcd(i,j) \\&=\prod_{d=1}^A \text{pow}(d,\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}[\gcd(i,j)=1]) \\&=\prod_{d=1}^A \text{pow}(d,\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}\sum_{x|i\ x|j}\mu(x)) \\&=\prod_{d=1}^A \text{pow}(d,\sum_{x=1}^{A/d}\mu(x)(A/(xd))(B/(xd))) \\&=\prod_{d=1}^A\prod_{x=1}^{A/d} \text{pow}(d,\mu(x)(A/(xd))(B/(xd))) \\&=\prod_{T=1}^A\prod_{d|T} \text{pow}(d,\mu(\frac{T}{d})(A/T)(B/T)) \\&=\prod_{T=1}^A\left(\prod_{d|T} d^{\mu(\frac{T}{d})}\right)^{(A/T)(B/T)} \\&=\prod_{T=1}^A mvp(T)^{(A/T)(B/T)} \end{aligned} \]

3

\(DC(n)=\frac{n(n+1)}{2}=1+\dots+n\)(Deng Cha)。

Mvp 的变形(机翻 deformation):

\[dmvp(n)=\left(\sum_{d|n}d^{\mu(\frac{n}{d})}\right)^{n^2} \]

她很类似,前缀积预处理配合上整除分块可以 \(O(\sqrt n\log n)\) 解决下面这个问题(设 \(A\le B\)):

\[\begin{aligned} G(A,B)&=\prod_{i=1}^A\prod_{j=1}^B\gcd(i,j)^{ij} \\&=\prod_{d=1}^A \text{pow}(d,\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}d^2ij[\gcd(i,j)=1]) \\&=\prod_{d=1}^A \text{pow}(d,\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}d^2ij\sum_{x|i\ x|j}\mu(x)) \\&=\prod_{d=1}^A \text{pow}(d,\sum_{x=1}^{A/d}\mu(x)d^2x^2\sum_{i=1}^{A/xd}i\sum_{j=1}^{B/xd}j) \\&=\prod_{d=1}^A\prod_{x=1}^{A/d} \text{pow}(d,\mu(x)(xd)^2 DC(A/xd)DC(B/xd)) \\&=\prod_{T=1}^A\prod_{d|T} \text{pow}(d,\mu(\frac{T}{d})T^2 DC(A/T)DC(B/T)) \\&=\prod_{T=1}^A dmvp(T)^{DC(A/T)DC(B/T)} \end{aligned} \]

简短の主干

看看我们要求的柿子:

\[\begin{aligned} \prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}\left(\frac{\text{lcm}(i,j)}{\gcd(i,k)}\right)^{f(type)}&=\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}\left(\frac{ij}{\gcd(i,j)\gcd(i,k)}\right)^{f(type)} \\&=\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}i^{f(type)}j^{f(type)}\gcd(i,j)^{-f(type)}\gcd(i,k)^{-f(type)} \end{aligned} \]

所以说我们转化成了两个子问题:

\[\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}i^{f(type)} \quad \prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}\gcd(i,j)^{f(type)} \]

type=0

\[\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}i=(A!)^{BC} \]

\[\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}\gcd(i,j)=\left(\prod_{i=1}^{A}\prod_{j=1}^{B}\gcd(i,j)\right)^C=F(A,B)^C \]

type=1

\[\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}i^{ijk}=\left(\prod_{i=1}^{A}i^i\right)^{DC(j)DC(k)} \]

里面的连乘预处理即可。

\[\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}\gcd(i,j)^{ijk}=\left(\prod_{i=1}^{A}\prod_{j=1}^{B}\gcd(i,j)^{ij}\right)^{DC(C)}=G(A,B)^{DC(C)} \]

type=2

注意到原柿子

\[\begin{aligned} \prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}\left(\frac{\text{lcm}(i,j)}{\gcd(i,k)}\right)^{\gcd(i,j,k)}&=\exp\ln\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}\left(\frac{\text{lcm}(i,j)}{\gcd(i,k)}\right)^{\gcd(i,j,k)} \\&=\exp\sum_{i=1}^{A}\sum_{j=1}^{B}\sum_{k=1}^{C}\gcd(i,j,k)\ln\left(\frac{\text{lcm}(i,j)}{\gcd(i,k)}\right) \\&=\exp\sum_{d=1}^{\min(A,B,C)}\varphi(d)\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}\sum_{k=1}^{C/d}\ln\left(\frac{\text{lcm}(di,dj)}{\gcd(di,dk)}\right) \\&=\exp\sum_{d=1}^{\min(A,B,C)}\varphi(d)\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}\sum_{k=1}^{C/d}\ln\left(\frac{\text{lcm}(i,j)}{\gcd(i,k)}\right) \\&=\prod_{d=1}^{\min(A,B,C)}\text{work}_{type=0}(A/d,B/d,C/d)^{\varphi(d)} \end{aligned} \]

所以就转化成了 type=0 的情形。

难算の时间

首先预处理是 \(O(n\log n)\) 的,因为有逆元。

type=0 和 type=1 均是 \(O(T\sqrt n\log n)\) 的,已经说过。

type=2 调用了 type=0,较为难算(以下比较符号均代表 \(O\) 的比较):

\[\begin{aligned} Time&\le\sum_{i=1}^{\sqrt n}\sqrt i\log i+\sum_{i=1}^{\sqrt n}\sqrt \frac{n}{i}\log \frac{n}{i} \\&=\int_1^{\sqrt n}\sqrt x\log x\, \text{d}x+\int_1^{\sqrt n}\sqrt\frac{n}{x}\log \frac{n}{x}\, \text{d}x \\&\le \log n\int_1^{\sqrt n}\sqrt x\, \text{d}x+\sqrt n\log n\int_1^{\sqrt n}\sqrt\frac{1}{x}\, \text{d}x \\&= \log n\ x^{3/2}|_{1}^{\sqrt n}+\sqrt n\log n\ x^{1/2}|_{1}^{\sqrt n} \\&=n^{3/4} \log n+n^{3/4} \log n \\&=n^{3/4} \log n \end{aligned} \]

所以总时间 \(O(n\log n+Tn^{3/4}\log n)\)

条理の代码

//We'll be counting stars.
#include<bits/stdc++.h>
using namespace std;
#define For(i,j,k) for(int i=(j),i##_=(k);i<=i##_;i++)
#define Rof(i,j,k) for(int i=(j),i##_=(k);i>=i##_;i--)
#define int long long
const int N=100000,M=100001;//number, memory
int mod,phi[M],mu[M],f[M],mp[M],mvp[M],imvp[M],dmvp[M],idmvp[M];
bool vis[M];
vector<int> p;
inline int pw(int x,int y){int r=1;while(y){if(y&1)r=r*x%mod;x=x*x%mod;y>>=1;}return r;}
inline int inv(int x){ return pw(x,mod-2); }
void init(){
	p.reserve(9593);
	phi[1]=mu[1]=1;
	For(i,2,N){
		if(!vis[i]){
			p.emplace_back(i);
			phi[i]=i-1,mu[i]=-1;
		}
		for(int j:p){
			if(i*j>=N) break;
			vis[i*j]=1;
			if(i%j==0){
				phi[i*j]=phi[i]*j,mu[i*j]=0;
				break;
			}else{
				phi[i*j]=phi[i]*(j-1),mu[i*j]=-mu[i];
			}
		}
	}
	For(i,1,N) phi[i]+=phi[i-1];
	f[0]=1; For(i,1,N) f[i]=f[i-1]*i%mod;
	mp[0]=1; For(i,1,N) mp[i]=mp[i-1]*pw(i,i)%mod;
	fill(mvp+1,mvp+N,1);
	int x;
	For(i,1,N){
		x=inv(i);
		For(j,1,N/i)
			if(mu[j]==1) (mvp[i*j]*=i)%=mod;
			else if(mu[j]==-1) (mvp[i*j]*=x)%=mod;
	}
	For(i,1,N) dmvp[i]=pw(mvp[i],i*i%(mod-1));
	mvp[0]=dmvp[0]=1;
	For(i,1,N) (mvp[i]*=mvp[i-1])%=mod;
	For(i,0,N) imvp[i]=inv(mvp[i]);
	For(i,1,N) (dmvp[i]*=dmvp[i-1])%=mod;
	For(i,0,N) idmvp[i]=inv(dmvp[i]);
}
inline int DC(int x){ return x*(x+1)/2%(mod-1); }
inline int F(int A,int B){
	if(A>B) swap(A,B);
	int ans=1;
	for(int l=1,r;l<=A;l=r+1){
		r=min(A/(A/l),B/(B/l));
		(ans*=pw(mvp[r]*imvp[l-1]%mod,(A/l)*(B/l)%(mod-1)))%=mod;
	}
	return ans;
}
inline int G(int A,int B){
	if(A>B) swap(A,B);
	int ans=1;
	for(int l=1,r;l<=A;l=r+1){
		r=min(A/(A/l),B/(B/l));
		(ans*=pw(dmvp[r]*idmvp[l-1]%mod,DC(A/l)*DC(B/l)%(mod-1)))%=mod;
	}
	return ans;
}
int work0(int A,int B,int C){
	return pw(pw(f[A],B)*pw(f[B],A)%mod,C)*
	inv(pw(F(A,B),C)*pw(F(A,C),B)%mod)%mod;
}
int work1(int A,int B,int C){
	return pw(pw(mp[A],DC(B))*pw(mp[B],DC(A))%mod,DC(C))*
	inv(pw(G(A,B),DC(C))*pw(G(A,C),DC(B))%mod)%mod;
}
int work2(int A,int B,int C){
	int ans=1,lim=min({A,B,C});
	for(int l=1,r;l<=lim;l=r+1){
		r=min({A/(A/l),B/(B/l),C/(C/l)});
		(ans*=pw(work0(A/l,B/l,C/l),(phi[r]-phi[l-1])%(mod-1)))%=mod;
	}
	return ans;
}
signed main(){
	int T,A,B,C;
	scanf("%lld%lld",&T,&mod);
	init();
	while(T--){
		scanf("%lld%lld%lld",&A,&B,&C);//A,B,C of 'work*()' CANNOT exchange!!!
		printf("%lld %lld %lld\n",work0(A,B,C),work1(A,B,C),work2(A,B,C));
	}
return 0;}
posted @ 2022-08-05 20:31  ShaoJia  阅读(49)  评论(0编辑  收藏  举报