• 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
    ",(int)solve(n,m));
        return 0;
    }
  • 相关阅读:
    网络
    DB
    DevOps
    Linux 进程管理:Supervisor
    Tomcat相关知识
    Tomcat配置和数据源配置
    Eclipse智能提示及部分快捷键
    Servlet工作原理
    蜗牛
    Servlet技术
  • 原文地址:https://www.cnblogs.com/shenben/p/6696501.html
Copyright © 2020-2023  润新知