题目
求∏i=1n∏j=1mFgcd(i,j)\prod_{i=1}^n\prod_{j=1}^mF_{gcd(i,j)}i=1∏nj=1∏mFgcd(i,j),F是斐波那契数列
分析
使n≤mn\leq mn≤m
=∏d=1nFd∑i=1n∑j=1m[gcd(i,j)==d]\large=\prod_{d=1}^n{F_d}^{\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==d]}=d=1∏nFd∑i=1n∑j=1m[gcd(i,j)==d]
重点是指数
∑i=1n∑j=1m[gcd(i,j)==d]=∑i=1⌊nd⌋∑j=1⌊md⌋[gcd(i,j)==1]\large\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==d]=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}[gcd(i,j)==1]i=1∑nj=1∑m[gcd(i,j)==d]=i=1∑⌊dn⌋j=1∑⌊dm⌋[gcd(i,j)==1]
=∑i=1⌊nd⌋∑j=1⌊md⌋∑k∣i,k∣jμ(k)\large=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\sum_{k|i,k|j}\mu(k)=i=1∑⌊dn⌋j=1∑⌊dm⌋k∣i,k∣j∑μ(k)
=∑k=1⌊nd⌋μ(k)⌊nkd⌋⌊mkd⌋\large=\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor}\mu(k)\lfloor\frac{n}{kd}\rfloor\lfloor\frac{m}{kd}\rfloor=k=1∑⌊dn⌋μ(k)⌊kdn⌋⌊kdm⌋
所以=∏d=1nFd∑k=1⌊nd⌋μ(k)⌊nkd⌋⌊mkd⌋\large=\prod_{d=1}^n{F_d}^{\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor}\mu(k)\lfloor\frac{n}{kd}\rfloor\lfloor\frac{m}{kd}\rfloor}=d=1∏nFd∑k=1⌊dn⌋μ(k)⌊kdn⌋⌊kdm⌋
令i=kdi=kdi=kd
∏i=1n(∏k∣iFkμ(ik))⌊ni⌋⌊mi⌋\large\prod_{i=1}^n(\prod_{k|i}F_{k}^{\mu(\frac{i}{k})})^{\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{i}\rfloor}i=1∏n(k∣i∏Fkμ(ki))⌊in⌋⌊im⌋
时间复杂度O(nlogn(logn+logmod)+qnlogmod)O(n\log n(\log n+\log mod)+q\sqrt n\log mod)O(nlogn(logn+logmod)+qnlogmod)
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int mod=1000000007,N=1000101;
int mu[N],dp[N],inv[N],prime[80001],cnt; bool v[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline signed ksm(int x,int y){
rr int ans=1;
for (;y;y>>=1,x=1ll*x*x%mod)
if (y&1) ans=1ll*ans*x%mod;
return ans;
}
inline void init(){
dp[0]=dp[1]=inv[1]=inv[0]=mu[1]=1;
for (rr int i=2;i<=N;++i){
dp[i]=inv[i]=1;
if (!v[i]) prime[++cnt]=i,mu[i]=-1;
for (rr int j=1;prime[j]*i<=N;++j){
v[i*prime[j]]=1;
if (i%prime[j]) mu[i*prime[j]]=-mu[i];
else break;
}
}
for (rr int i=1,a=1,b=0;i<=N;++i){
b=b+a-mod*(b+a>=mod),a=b-a+mod*(b<a);
rr int t[3]={ksm(b,mod-2),1,b};
for (rr int j=i,k=1;j<=N;j+=i,++k)
dp[j]=1ll*dp[j]*t[mu[k]+1]%mod,
inv[j]=1ll*inv[j]*t[1-mu[k]]%mod;
}
for (rr int i=1;i<=N;++i) dp[i]=1ll*dp[i-1]*dp[i]%mod,inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
signed main(){
init();
for (rr int t=iut();t;--t){
rr int n=iut(),m=iut();
if (n>m) n^=m,m^=n,n^=m;
rr int ans=1;
for (rr int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans=1ll*ans*ksm(1ll*dp[r]*inv[l-1]%mod,1ll*(n/l)*(m/l)%(mod-1))%mod;
}
print(ans); putchar(10);
}
return 0;
}