解法
首先觀察一下,可以發現對於a,b,正方形的邊長是lcm(a,b)。那麼買的地板的數量是
那麼對於一個n的答案就是:
因爲直接算看起來並不好算,所以考慮分成分子分母兩部分分別計算:
分子:
主要是分母:
現在可以計算的矩陣中每種gcd的個數,然後算出來分母的具體值
直接枚舉,然後計算矩陣中有多少個位置的gcd=d,設爲cnt(d)
這裏需要知道一個矩陣中有多少個位置互質:
考慮莫比烏斯反演
設這個式子的值爲
這個式子可以整除分塊做到
然後回頭計算每種gcd的個數:
計算分母:
然後又可以對S(n/d)整除分塊
細節:出現在冪的位置,所以對mod-1取模,而不是mod
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6+5;
const int mod=19260817;
inline int read(){
char c=getchar();int t=0,f=1;
while((!isdigit(c))&&(c!=EOF)){if(c=='-')f=-1;c=getchar();}
while((isdigit(c))&&(c!=EOF)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int t,n,s[maxn],rec[maxn];
int mu[maxn],vis[maxn],p[maxn],cnt;
inline int am1(int x){
if(x<0)return x+mod-1;
return x>=(mod-1)?x-(mod-1):x;
}
void get(){
mu[1]=1;
for(int i=2;i<=1e6;i++){
if(!vis[i]){
mu[i]=-1;p[++cnt]=i;
}
for(int j=1;j<=cnt&&i*p[j]<=1e6;j++){
mu[i*p[j]]=-mu[i];vis[i*p[j]]=1;
if(i%p[j]==0){
mu[i*p[j]]=0;break;
}
}
}
for(int i=2;i<=1e6;i++)mu[i]=am1(mu[i]+mu[i-1]);
}
int inv[maxn];
inline int ksm(int a,int b){
int ans=1;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;b>>=1;
}
return ans;
}
inline int mul(int l,int r){
return rec[r]*inv[l-1]%mod*rec[r]%mod*inv[l-1]%mod;
}
inline int sum(int x){
if(s[x])return s[x];
int r,ans=0;
for(int l=1;l<=x;l=r+1){
r=(x/(x/l));
ans=am1(ans+am1(mu[r]-mu[l-1])*(x/l)%(mod-1)*(x/l)%(mod-1));
}
s[x]=ans;
return ans;
}
signed main(){
t=read();
rec[0]=1;inv[0]=1;
for(int i=1;i<=1e6;i++)rec[i]=rec[i-1]*i%mod;
inv[1000000]=ksm(rec[1000000],mod-2);
for(int i=1e6-1;i>=1;i--)inv[i]=inv[i+1]*(i+1)%mod;
get();
while(t--){
n=read();
int r,ans=1;
for(int l=1;l<=n;l=r+1){
r=(n/(n/l));
ans=1ll*ans*(ksm(mul(l,r),(sum(n/l))%(mod-1))%mod)%mod;
//printf("%d %d %d %d\n",l,r,mul(l,r),sum(n/l));
}
printf("%lld\n",ksm(rec[n],(2*n)%(mod-1))*ksm(ans,mod-2)%mod);
}
return 0;
}