[Sdoi2017]数字表格

[Sdoi2017]数字表格

http://www.lydsy.com/JudgeOnline/problem.php?id=4816

Time Limit: 50 Sec  Memory Limit: 128 MB

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

Sample Output

1
6
960

g(d)转化为  POI 2007 Zap

题目即解释参考 http://www.cnblogs.com/TheRoadToTheGold/p/6609495.html

转化提示:1、a^b * c^b = (a*c)^d

2、a^(b*c)  = (a^b)^c

预处理g的时候 会遇到 mul=-1,所以要处理 逆元

#include<cstdio>
#include<iostream>
#define N 1000101
using namespace std;
int mul[N],prime[N],cnt;
long long f[N],g[N],inver[N];
const int mod=1e9+7;
bool v[N];
int n,m;
long long mult(long long a,long long b )
{
    long long ans=1;
    for(;b;b>>=1,a=a*a%mod)
     if(b&1) ans=ans*a%mod;
    return ans;
}
void pre()
{
    mul[1]=1;
    for(int i=2;i<N;i++)
    {
        if(!v[i])
        {
            prime[++cnt]=i;
            mul[i]=-1;
        }
        for(int j=1;j<=cnt;j++)
        {
            if(prime[j]*i>N-1) break;
            v[i*prime[j]]=true;
            if(i%prime[j]==0) break;
            mul[i*prime[j]]=-mul[i];
        }
    }
    f[1]=1;
    for(int i=2;i<N;i++) f[i]=(f[i-1]+f[i-2])%mod;
    for(int i=1;i<N;i++) inver[i]=mult(f[i],mod-2);
    fill(g,g+N,1);
    for(int i=1;i<N;i++)
     for(int j=1;i*j<N;j++)
      if(mul[j])  g[i*j]= g[i*j]*(mul[j]==1 ? f[i] : inver[i])%mod;
    for(int i=1;i<N;i++) g[i]=g[i-1]*g[i]%mod;
}
void solve()
{
    long long ans=1;int j;
    if(n>m) swap(n,m);
    for(int i=1;i<=n;i=j+1)
    {
        j=min(n/(n/i),m/(m/i));
        ans=ans*mult(g[j]*mult(g[i-1],mod-2)%mod,(long long)(n/i)*(m/i))%mod;
    }
    printf("%lld\n",ans);
}
int main()
{
    /*freopen("product.in","r",stdin);
    freopen("product.out","w",stdout);*/
	pre();
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        solve();
    }
}

  

时间: 2024-10-13 11:02:30

[Sdoi2017]数字表格的相关文章

【BZOJ4816】[Sdoi2017]数字表格 莫比乌斯反演

[BZOJ4816][Sdoi2017]数字表格 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 有多组测试数据. 第一个一

BZOJ 4816: [Sdoi2017]数字表格

二次联通门 : BZOJ 4816: [Sdoi2017]数字表格 /* BZOJ 4816: [Sdoi2017]数字表格 莫比乌斯反演 妈呀,我的μ没有啦 */ #include <cstdio> #include <iostream> #define rg register #define Max 1000050 #define mo 1000000007 inline int min (int a, int b) { return a < b ? a : b; } i

[BZOJ4816][SDOI2017]数字表格(莫比乌斯反演)

4816: [Sdoi2017]数字表格 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1259  Solved: 625[Submit][Status][Discuss] 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)

Bzoj4816 [Sdoi2017]数字表格

Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 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个数,她想知道这

P3704 [SDOI2017]数字表格

#include<iostream> #include<cstdio> #include<cstring> #define LL long long #define maxn 1000009 #define N maxn+10 #define M 1000000007 using namespace std; int n,m; int q; LL ksm(LL a,LL p){ LL ans=1; for(;p;p>>=1,a=a*a%M){ if(p&am

codevs 5962 [SDOI2017]数字表格

输入描述 Input Description  [题解] 对于蓝色部分预处理前缀积. 然后在用除法分块搞一下. O(Q*sqrt(min(n,m))*logn+nlogn) #include<cstdio> #include<iostream> using namespace std; typedef long long ll; const int N=1e6+5; const ll mod=1e9+7; int T,n,m,tot,mu[N],prime[N/3];bool ch

BZOJ4816 Sdoi2017数字表格

一开始只推出O(TN)的做法,后来看了看发现再推一步就好了. 我们只需要枚举gcd就可以啦. 然后我们改变一下枚举顺序 设T为dk 预处理中间那部分前缀积就好了. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+10,mod=1e9+7; 4 int n,m,p[N/2],miu[N],g[N],f[N],inv[N],cnt;bool v[N]; 5 typedef long long ll; 6 int

【[SDOI2017]数字表格】

求 \[Ans=\prod_{i=1}^N\prod_{j=1}^MFib[(i,j)]\] 连乘的反演,其实并没有什么不一样 我们把套路柿子拿出来 \[F(n)=\sum_{i=1}^N\sum_{j=1}^M[n|(i,j)]=\left \lfloor \frac{N}{n} \right \rfloor\times \left \lfloor \frac{M}{n} \right \rfloor=\sum_{n|d}f(d)\] \[f(n)=\sum_{i=1}^N\sum_{j=1}

loj SDOI2017数字表格 先存下

\(\prod \limits_{i=1}^{n}\prod\limits_{j=1}^{m}f[gcd(i,j)]\) \(\prod\limits_{k=1}^{n}f[k]^{\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[gcd(i,j)==k]}\) 幂我们很熟悉 就是 \(g(x)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[gcd(i,j)==x]=\sum\limits_{i=1}^{\frac{n}