一、题目描述:
用
现在有一个
求这个表格所有数的乘积。共有
数据范围:
二、解题思路:
我迄今为止做过的最难的莫比乌斯反演题!
话不多说,直接开始推式子。
三、完整代码:
1 #include<iostream> 2 #define N 1000010 3 #define lim 1000000 4 #define ll long long 5 #define M 1000000007 6 using namespace std; 7 ll ans,f[N],g[N],inf[N],ing[N]; 8 int T,n,m,cnt,mu[N],p[N],vis[N]; 9 ll ksm(ll base,ll q) 10 { 11 ll res=1; 12 while(q){ 13 if(q&1) res*=base,res%=M; 14 base*=base,base%=M,q>>=1; 15 } 16 return res; 17 } 18 void pre_work() 19 { 20 mu[1]=f[1]=g[0]=ing[0]=1; 21 for(int i=2;i<=lim;i++) 22 f[i]=(f[i-1]+f[i-2])%M; 23 for(int i=1;i<=lim;i++) 24 inf[i]=ksm(f[i],M-2),g[i]=1; 25 for(int i=2;i<=lim;i++) 26 { 27 if(!vis[i]) p[++cnt]=i,mu[i]=-1; 28 for(int j=1;j<=cnt&&i*p[j]<=lim;j++) 29 { 30 vis[i*p[j]]=1; 31 if(i%p[j]==0)break; 32 mu[i*p[j]]=-mu[i]; 33 } 34 } 35 for(int i=1;i<=lim;i++) 36 for(ll j=i;j<=lim;j+=i) 37 { 38 if(mu[j/i]==1) g[j]=g[j]*f[i]%M; 39 if(mu[j/i]==-1) g[j]=g[j]*inf[i]%M; 40 } 41 for(int i=1;i<=lim;i++) 42 g[i]=g[i]*g[i-1]%M,ing[i]=ksm(g[i],M-2); 43 } 44 void solve() 45 { 46 cin>>n>>m; ans=1; 47 if(n>m) swap(n,m); 48 for(int l=1,r;l<=n;l=r+1) 49 { 50 r=min(n/(n/l),m/(m/l));ans%=M; 51 ans*=ksm(ing[l-1]*g[r]%M,1ll*(n/l)*(m/l)%(M-1)); 52 } 53 cout<<ans%M<<'\n'; 54 } 55 int main() 56 { 57 ios::sync_with_stdio(false); 58 cin.tie(0);cout.tie(0); 59 cin>>T;pre_work(); 60 for(int i=1;i<=T;i++) 61 solve(); 62 return 0; 63 }
四、写题心得:
收获很大,了解了一些套路和技巧。收获经验如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】