luogu P3704 [SDOI2017]数字表格

背景:

以下图片均来自我的 P D F PDF 文件,谢绝转载。

题目传送门:

https://www.luogu.org/problemnew/show/P3704

题意:

在这里插入图片描述

思路:

在这里插入图片描述
在这里插入图片描述

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define mod 1000000007
#define MAXN 1000010
using namespace std;
	int n,m;
	LL f[MAXN],mu[MAXN],tot[MAXN];
	int prime[MAXN];
	bool bz[MAXN];
LL dg(LL x,LL k)
{
	if(!k) return 1;
	LL o=dg(x,k>>1);
	return k&1?o*o%mod*x%mod:o*o%mod;
}
LL inv(LL x,LL y)
{
	return x*dg(y,mod-2)%mod;
}
void init(int ma)
{
	mu[1]=1;
	bz[0]=bz[1]=true;
	int t=0;
	for(int i=2;i<=ma;i++)
	{
		if(!bz[i]) prime[++t]=i,mu[i]=-1;
		for(int j=1;j<=t&&(LL)i*prime[j]<=ma;j++)
		{
			bz[i*prime[j]]=true;
			if(!(i%prime[j]))
			{
				mu[i*prime[j]]=0;
				break;
			}
			mu[i*prime[j]]=-mu[i];
		}
	}
	
	f[0]=0,f[1]=1;
	tot[0]=tot[1]=1;
	for(int i=2;i<=ma;i++)
	{
		f[i]=(f[i-1]+f[i-2])%mod;
		tot[i]=1;
	}
	
	for(int i=1;i<=ma;i++)
	{
		LL o=inv(1,f[i]);
		for(int j=i;j<=ma;j+=i)
			if(mu[j/i]==1) tot[j]=tot[j]*f[i]%mod;
			else if(mu[j/i]==-1) tot[j]=tot[j]*o%mod;
	}
	
	for(int i=1;i<=ma;i++)
		tot[i]=tot[i]*tot[i-1]%mod;
}
LL solve(int n,int m)
{
	LL ans=1;
	for(int l=1,r;l<=min(n,m);l=r+1)
	{
		r=min(n/(n/l),m/(m/l));
		ans=ans*dg(tot[r]*inv(1,tot[l-1])%mod,((LL)n/l)*((LL)m/l))%mod;
	}
	return ans;
}
int main()
{
	int T;
	init(MAXN);
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d %d",&n,&m);
		printf("%lld\n",solve(n,m));
	}
}

猜你喜欢

转载自blog.csdn.net/zsyz_ZZY/article/details/84987564
今日推荐