山东OI2017-数字表格

来源:互联网 发布:淘宝企业偿债能力分析 编辑:程序博客网 时间:2024/04/30 17:41

O(n^2)——–>O(nlogn)
莫比乌斯、枚举约数
注意:逆元

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int mod = 1000000007;const int N = 1000000;const int mx = 1000010;int prime[80000],mu[mx],n,m,tot,ans;int sf[mx],fib[mx],invf[mx],sg[mx],g[mx],invg[mx];bool nop[mx];int fun(int n,int k) {    LL s=1;    while (k) {        if (k&1) s=s*n%mod;        n=1LL*n*n%mod;        k>>=1;    }    return (int)s;}int main() {    mu[1]=fib[1]=fib[2]=sf[1]=g[1]=1;    for (LL i=2; i<=N; ++i) {        if (!nop[i]) {            prime[tot++]=i;            mu[i]=-1;        }        for (LL j=0; j<tot; ++j) {            if (i*prime[j]>N) break;            nop[i*prime[j]]=true;            if (i%prime[j]==0) {                mu[i*prime[j]]=0;                break;            } else mu[i*prime[j]]=-mu[i];        }        fib[i]=fib[i-1]+fib[i-2];        if (fib[i]>=mod) fib[i]-=mod;        sf[i]=1LL*sf[i-1]*fib[i]%mod;        g[i]=1;    }    sg[1]=invg[0]=invg[1]=invf[0]=invf[1]=1;    invf[N]=fun(sf[N],mod-2);    for (int i=N; i>=2; --i)        invf[i-1]=1LL*invf[i]*fib[i]%mod,                  invf[i]=1LL*invf[i]*sf[i-1]%mod;    for (int i=2; i<=N; ++i) {        for (int j=1; i*j<=N; ++j)            if (mu[j]==1)                g[i*j]=1LL*g[i*j]*fib[i]%mod;            else if (mu[j]==-1)                g[i*j]=1LL*g[i*j]*invf[i]%mod;        sg[i]=1LL*sg[i-1]*g[i]%mod;    }    invg[N]=fun(sg[N],mod-2);    for (int i=N; i>=2; --i) invg[i-1]=1LL*invg[i]*g[i]%mod;    int T;    scanf("%d",&T);    while (T--) {        scanf("%d%d",&n,&m);        if (n>m) swap(n,m);        ans=1;        for (int last,i=1; i<=n; i=last+1)            last=min(n/(n/i),m/(m/i)),            ans=1LL*ans*fun(1LL*sg[last]*invg[i-1]%mod,1LL*(n/i)*(m/i)%(mod-1))%mod;        printf("%d\n",ans);    }    return 0;}
原创粉丝点击