Bzoj4816 [Sdoi2017]数字表格
Submit: 646 Solved: 296
Description
Doris刚刚学习了fibonacci数列。用f[i]表示数列的第i项,那么
f[0]=0
f[1]=1
f[n]=f[n-1]+f[n-2],n>=2
Doris用老师的超级计算机生成了一个n×m的表格,第i行第j列的格子中的数是f[gcd(i,j)],其中gcd(i,j)表示i,
j的最大公约数。Doris的表格中共有n×m个数,她想知道这些数的乘积是多少。答案对10^9+7取模。
Input
有多组测试数据。
第一个一个数T,表示数据组数。
接下来T行,每行两个数n,m
T<=1000,1<=n,m<=10^6
Output
输出T行,第i行的数是第i组数据的结果
Sample Input
3
2 3
4 5
6 7
2 3
4 5
6 7
Sample Output
1
6
960
6
960
HINT
Source
数学问题 莫比乌斯反演 分块
推公式+分块
推出来的那个子函数不是积性函数,需要$O(nlogn)$ 筛出来
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define LL long long 7 using namespace std; 8 const int mxn=1000005; 9 const int mod=1e9+7; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 int pri[mxn],mu[mxn],f[mxn],cnt=0; 17 LL g[mxn]; 18 bool vis[mxn]; 19 LL ksm(LL a,LL k){ 20 LL res=1; 21 while(k){ 22 if(k&1)res=res*a%mod; 23 a=a*a%mod; 24 k>>=1; 25 } 26 return res; 27 } 28 void init(){ 29 f[1]=1;g[0]=1;mu[1]=1; 30 for(int i=2;i<mxn;i++)f[i]=((LL)f[i-1]+f[i-2])%mod; 31 for(int i=2;i<mxn;i++){ 32 if(!vis[i]){pri[++cnt]=i;mu[i]=-1;} 33 for(int j=1;j<=cnt && (LL)pri[j]*i<mxn;j++){ 34 int tmp=pri[j]*i; 35 vis[tmp]=1; 36 if(i%pri[j]==0){mu[tmp]=0;break;} 37 mu[tmp]=-mu[i]; 38 } 39 } 40 for(int i=1;i<mxn;i++)g[i]=1; 41 for(int i=1;i<mxn;i++){ 42 LL invi=ksm(f[i],mod-2); 43 for(int j=i,c=1;j<mxn;j+=i,c++){ 44 if(!mu[c])continue; 45 if(mu[c]==1)g[j]=(LL)g[j]*f[i]%mod; 46 else g[j]=(LL)g[j]*invi%mod; 47 } 48 } 49 for(int i=2;i<mxn;i++)g[i]=(LL)g[i]*g[i-1]%mod; 50 return; 51 } 52 void calc(int n,int m){ 53 if(n>m)swap(n,m); 54 LL ans=1; 55 for(int i=1,pos;i<=n;i=pos+1){ 56 LL x=n/i,y=m/i; 57 pos=min(n/x,m/y); 58 LL inv=ksm(g[i-1],mod-2); 59 ans=ans*ksm(g[pos]*inv%mod,(LL)x*y%(mod-1))%mod; 60 } 61 printf("%lld\n",ans); 62 return; 63 } 64 int n,m; 65 int main(){ 66 // freopen("product.in","r",stdin); 67 // freopen("product.out","w",stdout); 68 int i,j; 69 int T=read(); 70 init(); 71 while(T--){ 72 n=read();m=read(); 73 calc(n,m); 74 } 75 return 0; 76 }
本文为博主原创文章,转载请注明出处。