1. 程式人生 > >luogu P3704 [SDOI2017]數字表格

luogu P3704 [SDOI2017]數字表格

背景:

以下圖片均來自我的 P D F PDF 檔案,謝絕轉載。

題目傳送門:

https://www.luogu.org/problemnew/show/P3704

題意:

在這裡插入圖片描述

思路:

在這裡插入圖片描述
在這裡插入圖片描述

程式碼:

#include<cstdio>
#include
<cstring>
#include<algorithm> #define LL long long #define mod 1000000007 #define MAXN 1000010 using namespace std; int n,m; LL f[MAXN],mu[MAXN],tot[MAXN]; int prime[MAXN]; bool bz[MAXN]; LL dg(LL x,LL k) { if(!k) return 1; LL o=dg(x,k>>1); return k&1?o*o%mod*x%mod:o*o%mod; } LL inv(
LL x,LL y) { return x*dg(y,mod-2)%mod; } void init(int ma) { mu[1]=1; bz[0]=bz[1]=true; int t=0; for(int i=2;i<=ma;i++) { if(!bz[i]) prime[++t]=i,mu[i]=-1; for(int j=1;j<=t&&(LL)i*prime[j]<=ma;j++) { bz[i*prime[j]]=true; if(!(i%prime[j])) { mu[i*prime[j]]=0; break
; } mu[i*prime[j]]=-mu[i]; } } f[0]=0,f[1]=1; tot[0]=tot[1]=1; for(int i=2;i<=ma;i++) { f[i]=(f[i-1]+f[i-2])%mod; tot[i]=1; } for(int i=1;i<=ma;i++) { LL o=inv(1,f[i]); for(int j=i;j<=ma;j+=i) if(mu[j/i]==1) tot[j]=tot[j]*f[i]%mod; else if(mu[j/i]==-1) tot[j]=tot[j]*o%mod; } for(int i=1;i<=ma;i++) tot[i]=tot[i]*tot[i-1]%mod; } LL solve(int n,int m) { LL ans=1; for(int l=1,r;l<=min(n,m);l=r+1) { r=min(n/(n/l),m/(m/l)); ans=ans*dg(tot[r]*inv(1,tot[l-1])%mod,((LL)n/l)*((LL)m/l))%mod; } return ans; } int main() { int T; init(MAXN); scanf("%d",&T); while(T--) { scanf("%d %d",&n,&m); printf("%lld\n",solve(n,m)); } }