题意:定义矩阵内每个位置(i,j)(i,j)(i,j)的数为gcd(i,j)\gcd(i,j)gcd(i,j),求矩阵内所有数的乘积。
∏k=1nFk∑i=1n∑j=1m[gcd(i,j)=k]
\prod^{n}_{k=1}F_k^{\sum^n_{i=1}\sum^{m}_{j=1}[\gcd(i,j)=k]}
k=1∏nFk∑i=1n∑j=1m[gcd(i,j)=k]
对于左上角的东西直接提出kkk
∑i=1⌊nk⌋∑j=1⌊mk⌋[gcd(i,j)=1]=∑d=1⌊nk⌋μ(d)⌊nk×d⌋⌊mk×d⌋
\sum^{\lfloor\frac{n}{k}\rfloor}_{i=1}\sum^{\lfloor\frac{m}{k}\rfloor}_{j=1}[\gcd(i,j)=1]\\=\sum^{\lfloor\frac{n}{k}\rfloor}_{d=1}\mu(d)\lfloor\frac{n}{k\times d}\rfloor\lfloor\frac{m}{k\times d}\rfloor
i=1∑⌊kn⌋j=1∑⌊km⌋[gcd(i,j)=1]=d=1∑⌊kn⌋μ(d)⌊k×dn⌋⌊k×dm⌋
于是原式就化为
∏R=1n(∏T∣RFTμ(RT))⌊nR⌋×⌊mR⌋
\prod^{n}_{R=1}(\prod_{T|R}F_T^{\mu(\frac{R}{T})})^{\lfloor\frac{n}{R}\rfloor\times \lfloor\frac{m}{R}\rfloor}
R=1∏n(T∣R∏FTμ(TR))⌊Rn⌋×⌊Rm⌋
预处理一下
∏T∣RFTμ(RT)
\prod_{T|R}F_T^{\mu(\frac{R}{T})}
T∣R∏FTμ(TR)
然后数论分块即可。
code:code:code:
#include <bits/stdc++.h>
#define int long long
#define regi register int
#define mod 1000000007
int T,n,m;
int vis[1000001],prime[1000001],mu[1000001],fi[1000001],power[1000001];
int tot;
inline int read(){
int r=0,w=0,c;
for(;!isdigit(c=getchar());r=c);
for(w=c^48;isdigit(c=getchar());w=w*10+(c^48));
return r^45?w:-w;
}
inline int ksm(int x,long long y,long long z=1){
for(;y;(z*=y&1?1LL*x:1LL*1)%=mod,y>>=1,(x*=x)%=mod);
return z%mod;
}
main(){
fi[1]=fi[2]=1;
for(regi i=3;i<=1000000;++i)
fi[i]=(fi[i-1]+fi[i-2])%mod;
mu[1]=1;
for(regi i=2;i<=1000000;++i){
if(!vis[i]){
prime[++tot]=i;
mu[i]=-1;
}
for(regi j=1;j<=tot&&i*prime[j]<=1000000;++j){
vis[i*prime[j]]=1;
if(i%prime[j])
mu[i*prime[j]]=mu[i]*mu[prime[j]];
else{
mu[i*prime[j]]=0;
break;
}
}
}
for(regi i=0;i<=1000000;++i)
power[i]=1;
for(regi i=1;i<=1000000;++i){
int invfi=ksm(fi[i],mod-2);
for(regi j=i;j<=1000000;j+=i){
if(mu[j/i]==-1)
(power[j]*=invfi)%=mod;
else if(mu[j/i]==1)
(power[j]*=fi[i])%=mod;
}
}
for(regi i=1;i<=1000000;++i)
power[i]=power[i]*power[i-1]%mod;
T=read();
while(T--){
n=read(),m=read();
if(n>m)
std::swap(n,m);
int ans=1;
for(regi i=1,j;i<=n;i=j+1){
j=std::min(n/(n/i),m/(m/i));
(ans*=ksm(power[j]*ksm(power[i-1],mod-2)%mod,1LL*(n/i)*(m/i)))%=mod;
}
printf("%lld\n",ans);
}
return 0;
}