/youl 乐团 题解
P5518 [MtOI2019]幽灵乐团 / 莫比乌斯反演基础练习题
以下 表示下取整除法(时间复杂度除外),分数线才是真正的除法。
以下时间复杂度中的 表示 。
对于不平常的柿子推导顺序,深感抱歉。
冗长の前置
0
注意别将 和 搞混,并且清楚他们的基础变换。
1
明白这个转换( 为任意函数):
2
今天的 mvp 是(因为等会儿会用得多,先写上来):
(没错起名就是这么随意)
她的前缀积预处理配合上整除分块可以 解决这个问题(由对称性,不妨设 ;幂太长了,用 代替):
3
设 (Deng Cha)。
Mvp 的变形(机翻 deformation):
她很类似,前缀积预处理配合上整除分块可以 解决下面这个问题(设 ):
简短の主干
看看我们要求的柿子:
所以说我们转化成了两个子问题:
type=0
type=1
里面的连乘预处理即可。
type=2
注意到原柿子
所以就转化成了 type=0 的情形。
难算の时间
首先预处理是 的,因为有逆元。
type=0 和 type=1 均是 的,已经说过。
type=2 调用了 type=0,较为难算(以下比较符号均代表 的比较):
所以总时间 。
条理の代码
//We'll be counting stars. #include<bits/stdc++.h> using namespace std; #define For(i,j,k) for(int i=(j),i##_=(k);i<=i##_;i++) #define Rof(i,j,k) for(int i=(j),i##_=(k);i>=i##_;i--) #define int long long const int N=100000,M=100001;//number, memory int mod,phi[M],mu[M],f[M],mp[M],mvp[M],imvp[M],dmvp[M],idmvp[M]; bool vis[M]; vector<int> p; inline int pw(int x,int y){int r=1;while(y){if(y&1)r=r*x%mod;x=x*x%mod;y>>=1;}return r;} inline int inv(int x){ return pw(x,mod-2); } void init(){ p.reserve(9593); phi[1]=mu[1]=1; For(i,2,N){ if(!vis[i]){ p.emplace_back(i); phi[i]=i-1,mu[i]=-1; } for(int j:p){ if(i*j>=N) break; vis[i*j]=1; if(i%j==0){ phi[i*j]=phi[i]*j,mu[i*j]=0; break; }else{ phi[i*j]=phi[i]*(j-1),mu[i*j]=-mu[i]; } } } For(i,1,N) phi[i]+=phi[i-1]; f[0]=1; For(i,1,N) f[i]=f[i-1]*i%mod; mp[0]=1; For(i,1,N) mp[i]=mp[i-1]*pw(i,i)%mod; fill(mvp+1,mvp+N,1); int x; For(i,1,N){ x=inv(i); For(j,1,N/i) if(mu[j]==1) (mvp[i*j]*=i)%=mod; else if(mu[j]==-1) (mvp[i*j]*=x)%=mod; } For(i,1,N) dmvp[i]=pw(mvp[i],i*i%(mod-1)); mvp[0]=dmvp[0]=1; For(i,1,N) (mvp[i]*=mvp[i-1])%=mod; For(i,0,N) imvp[i]=inv(mvp[i]); For(i,1,N) (dmvp[i]*=dmvp[i-1])%=mod; For(i,0,N) idmvp[i]=inv(dmvp[i]); } inline int DC(int x){ return x*(x+1)/2%(mod-1); } inline int F(int A,int B){ if(A>B) swap(A,B); int ans=1; for(int l=1,r;l<=A;l=r+1){ r=min(A/(A/l),B/(B/l)); (ans*=pw(mvp[r]*imvp[l-1]%mod,(A/l)*(B/l)%(mod-1)))%=mod; } return ans; } inline int G(int A,int B){ if(A>B) swap(A,B); int ans=1; for(int l=1,r;l<=A;l=r+1){ r=min(A/(A/l),B/(B/l)); (ans*=pw(dmvp[r]*idmvp[l-1]%mod,DC(A/l)*DC(B/l)%(mod-1)))%=mod; } return ans; } int work0(int A,int B,int C){ return pw(pw(f[A],B)*pw(f[B],A)%mod,C)* inv(pw(F(A,B),C)*pw(F(A,C),B)%mod)%mod; } int work1(int A,int B,int C){ return pw(pw(mp[A],DC(B))*pw(mp[B],DC(A))%mod,DC(C))* inv(pw(G(A,B),DC(C))*pw(G(A,C),DC(B))%mod)%mod; } int work2(int A,int B,int C){ int ans=1,lim=min({A,B,C}); for(int l=1,r;l<=lim;l=r+1){ r=min({A/(A/l),B/(B/l),C/(C/l)}); (ans*=pw(work0(A/l,B/l,C/l),(phi[r]-phi[l-1])%(mod-1)))%=mod; } return ans; } signed main(){ int T,A,B,C; scanf("%lld%lld",&T,&mod); init(); while(T--){ scanf("%lld%lld%lld",&A,&B,&C);//A,B,C of 'work*()' CANNOT exchange!!! printf("%lld %lld %lld\n",work0(A,B,C),work1(A,B,C),work2(A,B,C)); } return 0;}
本文来自博客园,作者:ShaoJia,版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义