luoguP5518 [MtOI2019]幽灵乐团 / 莫比乌斯反演基础练习题
一道毒瘤题目,题目链接:luoguP5518。
题意
题目大意:求 。
其中 , 。
题解
让我们先来颓一下柿子。
实际上只需要知道 和 的求法就可以了。
所以我们一共要推 个式子。
type=0
第一个式子直接预处理阶乘,然后算 次方。
第二个式子可以通过预处理筛出 ,然后快速幂。
如果想要更快可以筛出所有 的前缀积,然后数论分块。
type=1
第二个式子计算方式和type=0差不多,第一个式子只需要预处理 的前缀积即可。
type=2
然后你就会发现分子的右边的式子和分母的左边的式子约掉了。
于是我们现在只需要求 和 。
第一个式子只需要预处理阶乘、 的前缀和,然后就可以分块。
第二个式子还需要推一推。
然后你会发现 是可以预处理的。
于是乎,两遍整除分块就可以了。
最终时间复杂度是 的。
代码:
#include<algorithm>
#include<cstdio>
#include<map>
using namespace std;
using ll=long long;
inline int read()
{
int s=0,w=1;char ch;
while((ch=getchar())>'9'||ch<'0') if(ch=='-') w=-1;
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
int mod;
ll qow(ll a,int b)
{
b=(b%(mod-1)+mod-1)%(mod-1);
a%=mod;
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
map<int,ll>jyh[100001];
ll prephi[100001];
int pri[100001];
bool is[100001];
int phi[100001];
int pm[100001];
int mu[100001];
ll jc1[100001];
ll jc2[100001];
ll d1[100001];
ll d2[100001];
int A,B,C;
inline ll f(int i){ return 1ll*i*(i+1)/2%(mod-1);}
inline ll get2(int A,int B)
{
ll ans=jyh[A][B];
if(ans) return ans;
ans=1;
int E=min(A,B);
for(int lTp=1,rTp;lTp<=E;lTp=rTp+1)
{
rTp=min(A/(A/lTp),B/(B/lTp));
ll val=d1[rTp]*d2[lTp-1]%mod;
ans=ans*qow(val,(ll)(A/lTp)*(B/rTp)%(mod-1))%mod;
}
return jyh[A][B]=ans;
}
inline ll get1(int A,int B,int C)
{
ll ans=1;
int D=min(min(A,B),C);
for(int lT=1,rT;lT<=D;lT=rT+1)
{
rT=min(min(A/(A/lT),B/(B/lT)),C/(C/lT));
ans=ans*qow(get2(A/lT,B/lT),(prephi[rT]-prephi[lT-1])%(mod-1)*(C/lT)%(mod-1))%mod
*qow(get2(A/lT,C/lT),(prephi[rT]-prephi[lT-1])%(mod-1)*(B/lT)%(mod-1))%mod;
}
return ans;
}
inline ll get3(int A,int B,int C)
{
ll ans=1;
for(int lT=1,rT;lT<=A&&lT<=B&&lT<=C;lT=rT+1)
{
rT=min(min(A/(A/lT),B/(B/lT)),C/(C/lT));
ans=ans*qow(jc1[A/lT],(prephi[rT]-prephi[lT-1])%(mod-1)*(B/lT)*(C/lT)%(mod-1))%mod;
}
return ans;
}
int main()
{
int t=read(),n=100000;mod=read();
mu[1]=phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!is[i]) pri[++pri[0]]=i,mu[i]=-1,phi[i]=i-1;
for(int j=1;j<=pri[0]&&i*pri[j]<=n;j++)
{
is[i*pri[j]]=1;
if(i%pri[j]==0)
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
mu[i*pri[j]]=-mu[i];
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
for(int i=1;i<=pri[0];i++) for(ll j=pri[i];j<=n;j*=pri[i]) pm[j]=pri[i];
jc1[0]=jc2[0]=d1[0]=d2[0]=1;
for(int i=1;i<=n;i++)
{
d1[i]=1;
prephi[i]=prephi[i-1]+phi[i];
jc1[i]=jc1[i-1]*i%mod;
jc2[i]=jc2[i-1]*qow(i,i)%mod;
}
for(int i=1;i<=n;i++) for(int j=i;j<=n;j+=i)
d1[j]=d1[j]*qow(i,mu[j/i])%mod;
for(int i=2;i<=n;i++) d1[i]=(d1[i]*d1[i-1])%mod;
for(int i=1;i<=n;i++) d2[i]=qow(d1[i],mod-2);
while(t--)
{
A=read(),B=read(),C=read();
ll ans=1,val=1;
ans=ans*qow(jc1[A],1ll*B*C%(mod-1))%mod;
ans=ans*qow(jc1[B],1ll*A*C%(mod-1))%mod;
for(int i=1;i<=A&&i<=B;i++) if(pm[i])
val=val*qow(pm[i],1ll*(A/i)*(B/i)%(mod-1))%mod;
val=qow(val,C);
ans=ans*qow(val,mod-2)%mod,val=1;
for(int i=1;i<=A&&i<=C;i++) if(pm[i])
val=val*qow(pm[i],1ll*(A/i)*(C/i)%(mod-1))%mod;
val=qow(val,B);
ans=ans*qow(val,mod-2)%mod,val=1;
printf("%lld ",ans),ans=1;
ans=ans*qow(jc2[A],f(B)*f(C)%(mod-1))%mod;
ans=ans*qow(jc2[B],f(A)*f(C)%(mod-1))%mod;
for(int i=1;i<=A&&i<=B;i++) if(pm[i])
val=val*qow(pm[i],f(A/i)*f(B/i)%(mod-1)*i%(mod-1)*i%(mod-1))%mod;
val=qow(val,f(C));
ans=ans*qow(val,mod-2)%mod,val=1;
for(int i=1;i<=A&&i<=C;i++) if(pm[i])
val=val*qow(pm[i],f(A/i)*f(C/i)%(mod-1)*i%(mod-1)*i%(mod-1))%mod;
val=qow(val,f(B));
ans=ans*qow(val,mod-2)%mod,val=1;
printf("%lld ",ans),ans=1;
ans=qow(get1(A,B,C),mod-2);
ans=ans*get3(A,B,C)%mod*get3(B,A,C)%mod;
printf("%lld\n",ans);
}
return 0;
}
本文来自博客园,作者:Wuyanru,转载请取得作者同意并注明原文链接:https://www.cnblogs.com/Wuyanru/p/luoguP5518.html
本文内容如有侵权行为,请联系作者删除,qq:1395170470
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!