关于时间复杂度
查看原帖
关于时间复杂度
428358
Grisses楼主2023/11/15 21:43

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;
}
2023/11/15 21:43
加载中...