随笔 - 58,  文章 - 0,  评论 - 4,  阅读 - 3296

一、题目描述:

  用 fi 表示斐波那契数列的第 i 项,那么有:

  f0=0,f1=1;fn=fn1+fn2,n2

  现在有一个 nm 列的数字表格,第 i 行第 j 列的数字是 fgcd(i,j)

  求这个表格所有数的乘积。共有 T 组数据,答案对 109+7 取模。

  数据范围:1T103,1n,m106


 二、解题思路:

  我迄今为止做过的最难的莫比乌斯反演题!

  话不多说,直接开始推式子。

  i=1nj=1mf(gcd(i,j))=

  d=1ni=1nj=1m[gcd(i,j)=d]f(d)=

  d=1nf(d)i=1nj=1m[gcd(i,j)=d]=

  d=1nf(d)i=1n/dj=1m/d[gcd(i,j)=1]

  g(x,y)=i=1xj=1y[gcd(i,j)=1]

  =d=1nf(d)g(nd,md)

  g(x,y)=i=1xj=1y[gcd(i,j)=1]=

  i=1xj=1ydgcd(x,y)μ(d)=d=1xμ(d)×xdyd

  

  O(T×(n+n×log2n))

  

  g(x,y)=d=1nf(d)k=1n/dμ(k)×ndkmdk

  T=dk,=T=1n(dTf(d)μ(Td))nTmT

  g(x)=dxf(d)μ(xd),=T=1ng(T)nTmT

  g(x)!

  O((Tn+n)×log2n)


 三、完整代码:

复制代码
 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 }
复制代码

四、写题心得:

  收获很大,了解了一些套路和技巧。收获经验如下:

  1/=>Exp++!

  2西 O(nInn) =>Exp++!

  3 mod1  ! ap11 (modp) =>Exp++!

posted on   trh0630  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示