我是真的弱,推式子只能推一半
下面假设(n<m)
考虑题目要求的东西,可以考虑每个gcd的贡献,即$$prod_{d=1}{n}f[d]{sum_{i=1}{lfloorfrac{n}{d} floor}sum_{j=1}{lfloorfrac{m}{d} floor}[gcd(i,j)=1]}$$
由(n=sum_{d|n} mu[d]),得$$prod_{d=1}{n}f[d]{sum_{i=1}{lfloorfrac{n}{d} floor}sum_{j=1}{lfloorfrac{m}{d} floor}sum_{k|i,k|j}mu[k]}$$$$prod_{d=1}{n}f[d]{sum_{k=1}^{lfloorfrac{n}{d} floor}mu[k]lfloorfrac{n}{kd} floorlfloorfrac{m}{kd} floor}$$
大力数论分块即可获得60'好成绩
如果我们令(t=kd),然后把t提出来,即则$$prod_{t=1}{n}prod_{d|t}f[d]{lfloorfrac{n}{t} floorlfloorfrac{m}{t} floormu[lfloorfrac{n}{d} floor]}$$$$prod_{t=1}{n}(prod_{d|t}f[d]{mu[lfloorfrac{n}{d} floor]})^{lfloorfrac{n}{t} floorlfloorfrac{m}{t} floor}$$
里面的可以枚举每个数倍数预处理,然后就是数论分块
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define ldb long double
#define il inline
#define re register
using namespace std;
const int N=1e6+10,mod=1e9+7;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
il int fpow(int a,int b){int an=1;while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;}return an;}
bool v[N];
int prm[N],mu[N],tt,fb[N],ifb[N],f[N],ivf[N];
int main()
{
fb[0]=0,fb[1]=1,ifb[0]=ifb[1]=1;
for(int i=2;i<=N-10;++i) fb[i]=(fb[i-1]+fb[i-2])%mod,ifb[i]=fpow(fb[i],mod-2);
mu[1]=1;
for(int i=2;i<=N-10;++i)
{
if(!v[i]) v[i]=1,prm[++tt]=i,mu[i]=-1;
for(int j=1;j<=tt&&i*prm[j]<=N-10;++j)
{
v[i*prm[j]]=1,mu[i*prm[j]]=-mu[i];
if(i%prm[j]==0) {mu[i*prm[j]]=0;break;}
}
}
for(int i=0;i<=N-10;++i) f[i]=1;
for(int i=1;i<=N-10;++i)
for(int j=1;i*j<=N-10;++j)
f[i*j]=1ll*f[i*j]*((~mu[j])?fpow(fb[i],mu[j]):ifb[i])%mod;
ivf[0]=1;
for(int i=1;i<=N-10;++i) f[i]=1ll*f[i]*f[i-1]%mod,ivf[i]=fpow(f[i],mod-2);
int T=rd();
while(T--)
{
int n=rd(),m=rd(),ans=1;
if(n>m) swap(n,m);
for(int i=1,j;i<=n;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans=1ll*ans*fpow(1ll*f[j]*ivf[i-1]%mod,1ll*(m/i)*(n/i)%(mod-1))%mod;
}
printf("%d
",ans);
}
return 0;
}