rt,我认为我在问题3的思路与第一篇题解的思路相同,但是我的代码如果不记忆化数论分块的值的话会T,这是为什么?
代码:
#include<bits/stdc++.h>
#define int long long
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
int x=0,f=1;
char ch=nc();
while(ch<'0' or ch>'9')
{
if(ch=='-')f=-1;
ch=nc();
}
while(ch>='0' and ch<='9')x=(x<<3)+(x<<1)+(ch-'0'),ch=nc();
return x*f;
}
inline void write(int x){
if(x>9)write(x/10);
putchar(x%10+'0');
}
using namespace std;
int T,q,a,b,c,ans;
int tot,p[100005],mu[100005],sum[100005],C[100005],inc[100005],Fc[100005],Fcc[100005],inFcc[100005],phi[100005],F_mu[100005],CF_mu[100005],inF_mu[100005];
bool f[100005];
inline int fpow(int a,int b,const int mod){
if(b<0)return fpow(fpow(a,-b,mod),mod-2,mod);
a%=mod;
int res=1;
while(b){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
void ss(const int mod,const int mod_1){
mu[1]=1;
phi[1]=1;
for(int i=2;i<=100000;i++){
if(!f[i])p[++tot]=i,mu[i]=-1,phi[i]=i-1;
for(int j=1;j<=tot&&i*p[j]<=100000;j++){
f[i*p[j]]=1;
if(i%p[j]==0){
mu[i*p[j]]=0;
phi[i*p[j]]=phi[i]*p[j];
break;
}
mu[i*p[j]]=-mu[i];
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
for(int i=0;i<=100000;i++)F_mu[i]=1;
for(int i=1;i<=100000;i++){
for(int j=i;j<=100000;j+=i){
F_mu[j]=F_mu[j]*fpow(j/i,mu[i],mod)%mod;
}
}
// for(int i=1;i<=10;i++)cerr<<F_mu[i]<<' ';
// cerr<<endl;
CF_mu[0]=1;
for(int i=1;i<=100000;i++)CF_mu[i]=CF_mu[i-1]*F_mu[i]%mod;
inF_mu[100000]=fpow(CF_mu[100000],mod-2,mod);
for(int i=99999;i>=0;i--)inF_mu[i]=inF_mu[i+1]*F_mu[i+1]%mod;
for(int i=1;i<=100000;i++)sum[i]=(sum[i-1]+mu[i]*i%(mod_1)*i%(mod_1))%(mod_1);
C[0]=1;
for(int i=1;i<=100000;i++)C[i]=C[i-1]*i%mod;
inc[100000]=fpow(C[100000],mod-2,mod);
for(int i=99999;i>=0;i--)inc[i]=inc[i+1]*(i+1)%mod;
Fc[0]=1;
for(int i=1;i<=100000;i++)Fc[i]=Fc[i-1]*fpow(i,i,mod)%mod;
Fcc[0]=1;
for(int i=1;i<=100000;i++)Fcc[i]=Fcc[i-1]*fpow(i,i*i%(mod_1),mod)%mod;
inFcc[100000]=fpow(Fcc[100000],mod-2,mod);
for(int i=99999;i>=0;i--)inFcc[i]=inFcc[i+1]*fpow(i+1,(i+1)*(i+1)%(mod_1),mod)%mod;
for(int i=1;i<=100000;i++)phi[i]=(phi[i-1]+phi[i])%(mod_1);
for(int i=1;i<=100000;i++)mu[i]+=mu[i-1];
}
int Get1[1005][1005];
inline int get1(int a,int b,const int mod){
int res=0;
if(a>b)swap(a,b);
if(a<=1000&&b<=1000&&Get1[a][b]!=-1)return Get1[a][b];
for(int l=1,r;l<=a;l=r+1){
int x=a/l,y=b/l;
r=min(a/x,b/y);
// cerr<<"---"<<l<<' '<<r<<endl;
res=(res+(mu[r]-mu[l-1]+mod)%mod*x%mod*y%mod)%mod;
}
if(a<=1000&&b<=1000)Get1[a][b]=(res+mod)%mod;
return (res+mod)%mod;
}
inline int Solve1(int a,int b,int c,const int mod,const int mod_1){
int ans=fpow(C[a],b*c,mod)*fpow(C[b],a*c,mod)%mod;
int Q=1;
for(int l=1,r;l<=min(a,b);l=r+1){
int x=a/l,y=b/l;
r=min(a/x,b/y);
Q=Q*fpow(C[r]*inc[l-1]%mod,get1(x,y,mod_1)*c,mod)%mod;
}
for(int l=1,r;l<=min(a,c);l=r+1){
int x=a/l,z=c/l;
r=min(a/x,c/z);
Q=Q*fpow(C[r]*inc[l-1]%mod,get1(x,z,mod_1)*b,mod)%mod;
}
Q=fpow(Q,mod-2,mod);
return ans*Q%mod;
}
inline int sum1(int x,const int mod){
x%=mod;
return x*(x+1)/2%mod;
}
int Get2[1005][1005];
inline int get2(int a,int b,const int mod){
if(a>b)swap(a,b);
if(a<=1000&&b<=1000&&Get2[a][b]!=-1)return Get2[a][b];
int res=0;
for(int l=1,r;l<=a;l=r+1){
int x=a/l,y=b/l;
r=min(a/x,b/y);
res=(res+(sum[r]-sum[l-1]+mod)%mod*sum1(x,mod)%mod*sum1(y,mod)%mod+mod)%mod;
}
if(a<=1000&&b<=1000)Get2[a][b]=(res+mod)%mod;
return (res+mod)%mod;
}
inline int Solve2(int a,int b,int c,const int mod,const int mod_1){
int ans=fpow(Fc[a],sum1(b,mod_1)*sum1(c,mod_1),mod)*fpow(Fc[b],sum1(a,mod_1)*sum1(c,mod_1),mod)%mod;
int Q1=1,Q2=1;
for(int l=1,r;l<=min(a,b);l=r+1){
int x=a/l,y=b/l;
r=min(a/x,b/y);
Q1=Q1*fpow(Fcc[r]*inFcc[l-1]%mod,get2(x,y,mod_1),mod)%mod;
}
Q1=fpow(Q1,sum1(c,mod_1),mod);
for(int l=1,r;l<=min(a,c);l=r+1){
int x=a/l,z=c/l;
r=min(a/x,c/z);
Q2=Q2*fpow(Fcc[r]*inFcc[l-1]%mod,get2(x,z,mod_1),mod)%mod;
}
Q2=fpow(Q2,sum1(b,mod_1),mod)%mod;
int Q=fpow(Q1*Q2%mod,mod-2,mod);
return ans*Q%mod;
}
int Get3[1005][1005];
inline int get3(int a,int b,const int mod){
if(a<=1000&&b<=1000&&Get3[a][b]!=-1)return Get3[a][b];
const int mod_1=mod-1;
int res=1;
for(int l=1,r;l<=min(a,b);l=r+1){
int x=a/l,y=b/l;
r=min(a/x,b/y);
res=res*fpow(CF_mu[r]*inF_mu[l-1]%mod,x*y,mod)%mod;
}
if(a<=1000&&b<=1000)Get3[a][b]=(res+mod)%mod;
return (res+mod)%mod;
}
inline int Solve3(int a,int b,int c,const int mod,const int mod_1){
int ans=1;
int Q=1;
for(int l=1,r;l<=min({a,b,c});l=r+1){
int x=a/l,y=b/l,z=c/l;
r=min({a/x,b/y,c/z});
ans=ans*fpow(C[x],y*z%mod_1*(phi[r]-phi[l-1]+mod_1)%mod_1,mod)%mod;
ans=ans*fpow(C[y],x*z%mod_1*(phi[r]-phi[l-1]+mod_1)%mod_1,mod)%mod;
Q=Q*fpow(get3(x,y,mod),(phi[r]-phi[l-1]+(mod_1))%(mod_1)*z%(mod_1),mod)%mod;
Q=Q*fpow(get3(x,z,mod),(phi[r]-phi[l-1]+(mod_1))%(mod_1)*y%(mod_1),mod)%mod;
}
Q=fpow(Q,mod-2,mod);
return ans*Q%mod;
}
signed main()
{
T=read();q=read();
const int mod=q,mod_1=q-1;
ss(mod,mod_1);
memset(Get1,-1,sizeof(Get1));
memset(Get2,-1,sizeof(Get2));
memset(Get3,-1,sizeof(Get3));
while(T--){
a=read(),b=read(),c=read();
write(Solve1(a,b,c,mod,mod_1));putchar(' ');
write(Solve2(a,b,c,mod,mod_1));putchar(' ');
write(Solve3(a,b,c,mod,mod_1));putchar('\n');
}
return 0;
}