O(n^2)——–>O(nlogn)
莫比乌斯、枚举约数
注意:逆元
#include
using namespace std;
typedef long long LL;
const int mod = 1000000007;
const int N = 1000000;
const int mx = 1000010;
int prime[80000],mu[mx],n,m,tot,ans;
int sf[mx],fib[mx],invf[mx],sg[mx],g[mx],invg[mx];
bool nop[mx];
int fun(int n,int k) {
LL s=1;
while (k) {
if (k&1) s=s*n%mod;
n=1LL*n*n%mod;
k>>=1;
}
return (int)s;
}
int main() {
mu[1]=fib[1]=fib[2]=sf[1]=g[1]=1;
for (LL i=2; i<=N; ++i) {
if (!nop[i]) {
prime[tot++]=i;
mu[i]=-1;
}
for (LL j=0; jif (i*prime[j]>N) break;
nop[i*prime[j]]=true;
if (i%prime[j]==0) {
mu[i*prime[j]]=0;
break;
} else mu[i*prime[j]]=-mu[i];
}
fib[i]=fib[i-1]+fib[i-2];
if (fib[i]>=mod) fib[i]-=mod;
sf[i]=1LL*sf[i-1]*fib[i]%mod;
g[i]=1;
}
sg[1]=invg[0]=invg[1]=invf[0]=invf[1]=1;
invf[N]=fun(sf[N],mod-2);
for (int i=N; i>=2; --i)
invf[i-1]=1LL*invf[i]*fib[i]%mod,
invf[i]=1LL*invf[i]*sf[i-1]%mod;
for (int i=2; i<=N; ++i) {
for (int j=1; i*j<=N; ++j)
if (mu[j]==1)
g[i*j]=1LL*g[i*j]*fib[i]%mod;
else if (mu[j]==-1)
g[i*j]=1LL*g[i*j]*invf[i]%mod;
sg[i]=1LL*sg[i-1]*g[i]%mod;
}
invg[N]=fun(sg[N],mod-2);
for (int i=N; i>=2; --i) invg[i-1]=1LL*invg[i]*g[i]%mod;
int T;
scanf("%d",&T);
while (T--) {
scanf("%d%d",&n,&m);
if (n>m) swap(n,m);
ans=1;
for (int last,i=1; i<=n; i=last+1)
last=min(n/(n/i),m/(m/i)),
ans=1LL*ans*fun(1LL*sg[last]*invg[i-1]%mod,1LL*(n/i)*(m/i)%(mod-1))%mod;
printf("%d\n",ans);
}
return 0;
}