codevs 5962 [SDOI2017]数字表格

Posted 神犇(shenben)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 check[N];
ll f[N],invf[N],g[N];
ll fpow(ll a,ll p){
    ll res=1;
    for(;p;p>>=1,a=a*a%mod) if(p&1) res=res*a%mod;
    return res;
}
void pre(){
    mu[1]=1;n=1e6;
    for(int i=2;i<=n;i++){
        if(!check[i]) prime[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot&&i*prime[j]<=n;j++){
            check[i*prime[j]]=1;
            if(!(i%prime[j])){mu[i*prime[j]]=0;break;}
            else mu[i*prime[j]]=-mu[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++) invf[i]=fpow(f[i],mod-2);
    fill(g,g+n+1,1);
    for(int i=1;i<=n;i++){
        for(int j=1;i*j<=n;j++){
            if(mu[j]){
                g[i*j]=g[i*j]*(mu[j]==1?f[i]:invf[i])%mod;
            }
        }
    }
    for(int i=1;i<=n;i++) g[i]=g[i]*g[i-1]%mod;
}
ll solve(int n,int m){
    ll ans=1;
    if(n>m) swap(n,m);
    for(int i=1,pos;i<=n;i=pos+1){
        pos=min(n/(n/i),m/(m/i));
        ans=ans*fpow(g[pos]*fpow(g[i-1],mod-2)%mod,1LL*(n/i)*(m/i))%mod;
    }
    return ans;
}
int main(){
    pre();
    scanf("%d",&T);
    while(T--) scanf("%d%d",&n,&m),printf("%d\\n",(int)solve(n,m));
    return 0;
}

 

以上是关于codevs 5962 [SDOI2017]数字表格的主要内容,如果未能解决你的问题,请参考以下文章

codevs 5963 [SDOI2017]树点染色

codevs 5967 [SDOI2017]相关分析

codevs 5965 [SDOI2017]新生舞会

BZOJ 4816: [Sdoi2017]数字表格

[Sdoi2017]数字表格

P3704 [SDOI2017]数字表格