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]数字表格的主要内容,如果未能解决你的问题,请参考以下文章