码迷,mamicode.com
首页 > 其他好文 > 详细

[SDOI2017]数字表格

时间:2019-12-06 19:25:44      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:==   https   over   for   sdi   +=   define   href   形式   

题目链接:Click here

Solution:

先把原式写出来
\[ \prod_{i=1}^n \prod _{j=1}^m F_{gcd(i,j)}\\]
\(k=gcd(i,j)\),假设\(n\le m\)
\[ \prod_{i=1}^n \prod _{j=1}^m F_{t}\\prod_{k=1}^n F_k ^{(\sum _{i=1} ^{\lfloor \frac{n}{k} \rfloor} \sum _{j=1} ^{\lfloor \frac{m}{k} \rfloor} [gcd(i,j)=1])} \]
我们把指数提出了,发现是我们非常熟悉的形式
\[ \sum _{i=1} ^{\lfloor \frac{n}{k} \rfloor} \sum _{j=1} ^{\lfloor \frac{m}{k} \rfloor} [gcd(i,j)=1]\\sum _{i=1} ^{\lfloor \frac{n}{k} \rfloor} \sum _{j=1} ^{\lfloor \frac{m}{k} \rfloor} \sum _{t|i} \sum_{t|j} \mu(t)\\sum_{t=1}^{\lfloor \frac{n}{k} \rfloor} \mu(t) \lfloor \frac{n}{kt} \rfloor \lfloor \frac{m}{kt} \rfloor \]
那么现在式子变成了这个形式
\[ \prod_{k=1}^n F_k ^{(\sum_{t=1}^{\lfloor \frac{n}{k} \rfloor} \mu(t) \lfloor \frac{n}{kt} \rfloor \lfloor \frac{m}{kt} \rfloor)} \]
我们令\(T=kt\),然后枚举\(T\)
\[ \prod _{T=1} ^n(\sum_{k|T} F_k ^{\mu({{T} \over {}k})})^{\lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor} \]
我们设\(f(n)\)
\[ f(n)=\sum_{d|n} F_d ^{\mu ({n \over d})} \]
则原始为
\[ \prod _{T=1} ^n f(T) ^{\lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor} \]
那么我们暴力预处理出\(f(n)\)后数论分块即可

Code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+11;
const int mod=1e9+7;
bool vis[N];
int n,m,u[N],p[N],f[N],g[N];
int ans,cnt,F[N],I[N];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int qpow(int a,int b){
    int re=1;
    while(b){
        if(b&1) re=re*a%mod;
        b>>=1;a=a*a%mod;
    }return re;
}
void prepare(){
    u[1]=1;I[1]=F[1]=1;g[0]=g[1]=1;
    for(int i=2;i<N;i++){
        F[i]=(F[i-1]+F[i-2])%mod;
        I[i]=qpow(F[i],mod-2);
        if(!vis[i]) p[++cnt]=i,u[i]=-1;
        for(int j=1;j<=cnt&&i*p[j]<N;j++){
            vis[i*p[j]]=1;
            if(i%p[j]==0) break;
            u[i*p[j]]=-u[i];
        }
    }
    for(int i=1;i<N;i++) f[i]=1;
    for(int i=1;i<N;i++){
        if(!u[i]) continue;
        for(int j=i;j<N;j+=i)
            f[j]=f[j]*(u[i]==1?F[j/i]:I[j/i])%mod;
    }
    for(int i=2;i<N;i++) f[i]=f[i]*f[i-1]%mod;
    for(int i=2;i<N;i++) g[i]=qpow(f[i],mod-2);
}
void solve(){
    n=read(),m=read();
    ans=1;if(n>m) swap(n,m);
    for(int i=1,j;i<=n;i=j+1){
        j=min(n/(n/i),m/(m/i));
        int val=f[j]*g[i-1]%mod;
        ans=ans*qpow(val,(n/i)*(m/i))%mod;
    }
    printf("%lld\n",ans%mod);
}
signed main(){
    prepare();
    int t=read();
    while(t--) solve();
    return 0;
}

[SDOI2017]数字表格

标签:==   https   over   for   sdi   +=   define   href   形式   

原文地址:https://www.cnblogs.com/NLDQY/p/11996976.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!