@xiaoziyao
2020-04-09T21:19:18.000000Z
字数 16633
阅读 1264
解题报告
[MtOI2019]幽灵乐团解题报告:
题意:共组数据,给定求对于每个的,其中:
数据范围:
这道题的公式真的是精神污染。。。
首先我们可以将原式化为,因此我们可以分为两部分来做这道题,即求与
时:
第一个式子:
时:
第一个式子:
时
第一个式子:
#include<stdio.h>
const int maxn=100005;
long long i,j,k,m,n,T,p,A,B,C,l,r,cnt;
long long a[maxn],c[maxn],mu[maxn],varphi[maxn],fac1[maxn],fac2[maxn],w1[maxn],f1[maxn],g1[maxn],w2[maxn],f2[maxn],g2[maxn],w3[maxn],f3[maxn],g3[maxn],sum[maxn];
//a[i]={Prime},c[i]=[i\in{Prime}?]
//mu[i]=(i==1?)1:((i=\prod_{j=1}^s p_i,(p_x!=p_y(x!=y)))? 0:(-1)^s)
//fac1[i]=i!,fac2[i]=\prod_{j=1}^i i^i
//w1[i]=\prod_{d|i}i^{\mu(d/i)},f1[i]=\prod_{j=1}^i w1[i],g1[i]=f1[i]^{-1}
//w2[i]=w1[i]*(i^2),f2[i]=\prod_{j=1}^i w2[i],g2[i]=f2[i]^{-1}
//w3[i]=i^{\varphi(i)},f3[i]=\prod_{j=1]^i w3[i],g3[i]=f3[i]^{-1}
//sum[i]=\sum_{j=1}^i varphi[i]
inline long long min(long long a,long long b){
return a<b? a:b;
}
long long ksm(long long a,long long b,long long p){
long long res=1;
while(b>0){
if(b&1)
res=(res*a)%p;
a=(a*a)%p,b>>=1;
}
return res;
}
long long inv(long long a,long long b){
return ksm(a,b-2,b);
}
void init(){
c[1]=mu[1]=varphi[1]=1;
for(long long i=2;i<maxn;i++){
if(c[i]==0)
a[++cnt]=i,mu[i]=-1,varphi[i]=i-1;
for(long long j=1;j<=cnt;j++){
if(i*a[j]>=maxn)
break;
c[i*a[j]]=1;
if(i%a[j]==0){
mu[i*a[j]]=0;
varphi[i*a[j]]=varphi[i]*a[j];
break;
}
mu[i*a[j]]=-mu[i];
varphi[i*a[j]]=varphi[i]*(a[j]-1);
}
}
fac1[0]=1;
for(long long i=1;i<maxn;i++)
fac1[i]=fac1[i-1]*i%p;
fac2[0]=1;
for(long long i=1;i<maxn;i++)
fac2[i]=fac2[i-1]*ksm(i,i%(p-1),p)%p;
for(long long i=0;i<maxn;i++)
w1[i]=w2[i]=1;
for(long long i=1;i<maxn;i++){
if(mu[i]==0)
continue;
for(long long j=i;j<maxn;j+=i){
if(mu[i]==1)
w1[j]=(w1[j]*(j/i))%p;
if(mu[i]==-1)
w1[j]=(w1[j]*inv(j/i,p))%p;
}
}
f1[0]=g1[0]=1;
for(long long i=1;i<maxn;i++)
f1[i]=f1[i-1]*w1[i]%p,g1[i]=inv(f1[i],p);
for(long long i=1;i<maxn;i++)
w2[i]=ksm(w1[i],i*i%(p-1),p);
f2[0]=g2[0]=1;
for(long long i=1;i<maxn;i++)
f2[i]=f2[i-1]*w2[i]%p,g2[i]=inv(f2[i],p);
for(long long i=1;i<maxn;i++)
w3[i]=ksm(i,varphi[i],p);
f3[0]=g3[0]=1;
for(long long i=1;i<maxn;i++)
f3[i]=f3[i-1]*w3[i]%p,g3[i]=inv(f3[i],p);
for(long long i=1;i<maxn;i++)
sum[i]=sum[i-1]+varphi[i];
}
inline long long getsum(long long x,long long p){
return x*(x+1)/2%p;
}
long long getnmt(long long A,long long B,long long C,long long t){
if(t==0){
long long res=ksm(fac1[A],B*C%(p-1),p);
return res;
}
if(t==1){
long long res=ksm(fac2[A],getsum(B,p-1)*getsum(C,p-1)%(p-1),p);
return res;
}
if(t==2){
long long l=1,r,res=1;
while(l<=min(min(A,B),C)){
r=min(min(A/(A/l),B/(B/l)),C/(C/l));
res=res*ksm(f3[r]*g3[l-1]%p,(A/l)*(B/l)%(p-1)*(C/l)%(p-1),p)%p*ksm(fac1[A/l],(sum[r]-sum[l-1]+(p-1))%(p-1)*(B/l)%(p-1)*(C/l)%(p-1),p)%p;
l=r+1;
}
return res;
}
}
long long getres(long long A,long long B){
long long l=1,r,res=1;
while(l<=min(A,B)){
r=min(A/(A/l),B/(B/l));
res=res*ksm(f1[r]*g1[l-1]%p,(A/l)*(B/l)%(p-1),p)%p;
l=r+1;
}
return res;
}
long long getdmt(long long A,long long B,long long C,long long t){
if(t==0){
long long l=1,r,res=1;
while(l<=min(A,B)){
r=min(A/(A/l),B/(B/l));
res=(res*ksm(f1[r]*g1[l-1]%p,(A/l)*(B/l)%(p-1),p))%p;
l=r+1;
}
return ksm(res,C,p);
}
if(t==1){
long long l=1,r,res=1;
while(l<=min(A,B)){
r=min(A/(A/l),B/(B/l));
res=(res*ksm(f2[r]*g2[l-1]%p,getsum(A/l,p-1)*getsum(B/l,p-1)%(p-1),p))%p;
l=r+1;
}
return ksm(res,getsum(C,p-1),p);
}
if(t==2){
long long l=1,r,res=1;
while(l<=min(min(A,B),C)){
r=min(min(A/(A/l),B/(B/l)),C/(C/l));
res=res*ksm(getres(A/l,B/l),(sum[r]-sum[l-1]+(p-1))%(p-1)*(C/l)%(p-1),p)%p*ksm(f3[r]*g3[l-1]%p,(A/l)*(B/l)%(p-1)*(C/l)%(p-1),p)%p;
l=r+1;
}
return res;
}
}
long long getans(long long A,long long B,long long C,long long t){
long long nmt=getnmt(A,B,C,t)*getnmt(B,A,C,t)%p,dmt=getdmt(A,B,C,t)*getdmt(A,C,B,t)%p;
return nmt*inv(dmt,p)%p;
}
int main(){
scanf("%lld%lld",&T,&p);
init();
while(T--){
scanf("%lld%lld%lld",&A,&B,&C);
printf("%lld %lld %lld\n",getans(A,B,C,0),getans(A,B,C,1),getans(A,B,C,2));
}
return 0;
}