# 「MtOI2019」幽灵乐团

### Description

$\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}({[i,j]\over (i,k)})^{f(type)}$
$f(0)=1,f(1)=ijk,f(2)=(i,j,k)$

A,B,C<=10^5,T<=70

### Solution

M表示min(a,b,c)或min(a,b)

type=1直接预处理阶乘快速幂
type=2也是预处理$\prod_{i=1}^{n}i^i$快速幂
type=3推式子：
$\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}i^{(i,j,k)}$
$\prod_{d=1}^{M}\prod_{i=1}^{A/d}(id)^{d\sum_{j=1}^{B/d}\sum_{k=1}^{C/d}[(i,j,k)=1]}$
$\prod_{x=1}^{M}\prod_{d=1}^{M/x}\prod_{i=1}^{A/xd}(idx)^{d\mu(x)(B/xd)(C/xd)}$
$\prod_{T=1}^{M}\prod_{i=1}^{A/T}(iT)^{\sum_{d|T}d\mu(T/x)(B/T)(C/T)}$
$\prod_{T=1}^{M}\prod_{i=1}^{A/T}(iT)^{\varphi(T)(B/T)(C/T)}$

type=1求$\prod_{i=1}^{A}\prod_{j=1}^{B}(i,j)$再快速幂
$\prod_{d=1}^{M}d^{\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}[(i,j)=1]}$
$\prod_{x=1}^{M}\prod_{d=1}^{M/x}d^{(A/xd)(B/xd)\mu(x)}$
$\prod_{T=1}^{M}\prod_{d|T}d^{\mu(T/d)(A/T)(B/T)}$
n log n预处理+分块
type=2同理，不再过多阐述
type=3
$\prod_{i=1}^{A}\prod_{j=1}^{B}\prod_{k=1}^{C}(i,j)^{(i,j,k)}$
$\prod_{d=1}^{min(A,B)}d^{(\sum_{k=1}^{C}(k,d))(\sum_{i=1}^{A/d}\sum_{j=1}^{B/d}[(i,j)=1)]}$
$\prod_{x=1}^{min(A,B)}\prod_{d=1}^{min(A,B)/x}d^{\mu(x)(\sum_{k=1}^{C}(k,d))(A/xd)(B/xd)}$

$\sum_{T|d}T\sum_{k=1}^{C/T}[(k,d/T)=1]$
$\sum_{x|d}\mu(x)\sum_{T|{d\over x}}T(C/Tx)$
$\sum_{i|d}(C/i)\sum_{x|i}\mu(x){i\over x}$
$\sum_{i|d}(C/i)\varphi(i)$

$\prod_{i=1}^{M}i^{(C/i)\varphi(i)\sum_{x=1}^{min(A,B)/i}\sum_{d=1}^{min(A,B)/ix}\mu(x)(A/idx)(B/idx)}$

$\sum_{T=1}^{min(A,B)/i}(A/Ti)(B/Ti)\sum_{d|T}\mu(d)$

$\prod_{i=1}^{M}\prod_{x=1}^{min(A,B)/i}\prod_{d=1}^{min(A,B)/ix}d^{(C/i)\varphi(i)\mu(x)(A/idx)(B/idx)}$
$\prod_{i=1}^{M}\prod_{T=1}^{min(A,B)/i}\sum_{d|T}d^{\mu(T/d)(A/iT)(B/iT)(C/i)\varphi(i)}$，分块套分块即可

### Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long ll;

const int N=1e5+5;

int q,Mo,p[N],mu[N],phi[N];
bool vis[N];
ll f1[N],t1[N],f2[N],t2[N],s[N],f3[N],sp[N],Inv_t1[N],Inv_t2[N],a,b,c;

ll pwr(ll x,ll y) {
y%=Mo-1;if (y<0) y+=Mo-1;
ll z=1;
for(;y;y>>=1,x=x*x%Mo)
if (y&1) z=z*x%Mo;
return z;
}

ll Inv(ll x) {return pwr(x,Mo-2);}

ll S(ll x) {return x*(x+1)/2%(Mo-1);}

void pre(int N) {
mu[1]=phi[1]=1;
fo(i,2,N) {
if (!vis[i]) p[++p[0]]=i,mu[i]=-1,phi[i]=i-1;
fo(j,1,p[0]) {
int k=i*p[j];if (k>N) break;
vis[k]=1;if (!(i%p[j])) {phi[k]=phi[i]*p[j];break;}
mu[k]=-mu[i];phi[k]=phi[i]*(p[j]-1);
}
}

f1[0]=f2[0]=f3[0]=1;
fo(i,1,N) {
f1[i]=f1[i-1]*i%Mo;
f2[i]=f2[i-1]*pwr(i,i)%Mo;
f3[i]=f3[i-1]*pwr(i,phi[i])%Mo;
}

fo(i,0,N) t1[i]=t2[i]=1;
fo(d,1,N) fo(x,1,N/d) {
int now=pwr(d,mu[x]);
t1[d*x]=t1[d*x]*now%Mo;
t2[d*x]=t2[d*x]*now%Mo;
}
Inv_t1[0]=Inv_t2[0]=1;
fo(i,1,N) {
t1[i]=t1[i-1]*t1[i]%Mo;
t2[i]=t2[i-1]*pwr(t2[i],(ll)i*i)%Mo;
Inv_t1[i]=Inv(t1[i]);Inv_t2[i]=Inv(t2[i]);
sp[i]=(sp[i-1]+phi[i])%(Mo-1);
}
}

namespace Type_1{
ll calc(ll n,ll m) {
if (n>m) swap(n,m);
ll ans=1;
for(ll l=1,r=0;l<=n;l=r+1) {
r=min(n/(n/l),m/(m/l));
ans=ans*pwr(t1[r]*Inv_t1[l-1]%Mo,(n/l)*(m/r))%Mo;
}
return ans;
}
}

namespace Type_2{
ll calc(ll n,ll m) {
if (n>m) swap(n,m);
ll ans=1;
for(ll l=1,r=0;l<=n;l=r+1) {
r=min(n/(n/l),m/(m/l));
ans=ans*pwr(t2[r]*Inv_t2[l-1]%Mo,S(n/l)*S(m/l))%Mo;
}
return ans;
}
}

namespace Type_3{
ll calc(ll a,ll b) {
if (a>b) swap(a,b);
ll ans=1;
for(ll l=1,r=0;l<=a;l=r+1) {
r=min(a/(a/l),b/(b/l));
ans=ans*pwr(t1[r]*Inv_t1[l-1]%Mo,(a/l)*(b/l))%Mo;
}
return ans;
}
ll calc_1(ll a,ll b,ll c) {
ll ans=1;int m=min(min(a,b),c);
for(ll l=1,r=0;l<=m;l=r+1) {
r=min(min(a/(a/l),b/(b/l)),c/(c/l));
ll ret=(sp[r]-sp[l-1])%(Mo-1);
ans=ans*pwr(f1[a/l],(b/l)*(c/l)%(Mo-1)*ret)%Mo;
}
return ans;
}
ll calc_2(ll a,ll b,ll c) {
ll ans=1;int m=min(min(a,b),c);
for(ll l=1,r=0;l<=m;l=r+1) {
r=min(min(a/(a/l),b/(b/l)),c/(c/l));
ans=ans*pwr(calc(a/l,b/l),(sp[r]-sp[l-1])*(c/l))%Mo;
}
return ans;
}
}

int main() {
scanf("%d%d",&q,&Mo);
pre(1e5);
for(;q;q--) {
scanf("%lld%lld%lld",&a,&b,&c);
ll ans=pwr(f1[a],b*c)%Mo*pwr(f1[b],a*c)%Mo;
ans=ans*Inv(pwr(Type_1::calc(a,b),c))%Mo;
ans=ans*Inv(pwr(Type_1::calc(a,c),b))%Mo;
printf("%lld ",ans);
ans=pwr(f2[a],S(b)*S(c))*pwr(f2[b],S(a)*S(c))%Mo;
ans=ans*Inv(pwr(Type_2::calc(a,b),S(c)))%Mo;
ans=ans*Inv(pwr(Type_2::calc(a,c),S(b)))%Mo;
printf("%lld ",ans);
ans=Type_3::calc_1(a,b,c)*Type_3::calc_1(b,a,c)%Mo;
ans=ans*Inv(Type_3::calc_2(a,b,c))%Mo;
ans=ans*Inv(Type_3::calc_2(a,c,b))%Mo;
printf("%lld\n",ans);
}
return 0;
}


05-02 1116

09-08 248

11-04 106

04-01 45

#### 题解 [MtOI2019]小铃的烦恼

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。