luogu P2155 [SDOI2008]沙拉公主的困惑

背景:

写一下最近做的题目。

题目传送门:

https://www.luogu.org/problem/P2155

题意:

[ 1 , n ! ] [1,n!] [1,n!]内与 m ! m! m!互质的数的个数。

思路:

这个转化还是比较妙的。

考虑 [ 1 , m ! ] [1,m!] [1,m!]内与 m ! m! m!互质的数的个数,显然答案为 ϕ ( m ! ) \phi(m!) ϕ(m!)

考虑 ( m ! , n ! ] (m!,n!] (m!,n!]内与 m ! m! m!互质的数的个数。
考虑更相减损术: gcd ⁡ ( a , b ) = gcd ⁡ ( a + b , b ) \gcd(a,b)=\gcd(a+b,b) gcd(a,b)=gcd(a+b,b),因此想到 gcd ⁡ ( a , m ! ) = gcd ⁡ ( a + m ! , m ! ) = 1 \gcd(a,m!)=\gcd(a+m!,m!)=1 gcd(a,m!)=gcd(a+m!,m!)=1,因此相当于将 ϕ ( m ! ) \phi(m!) ϕ(m!) n ! m ! \frac{n!}{m!} m!n!倍。

综上 a n s = n ! m ! ϕ ( m ! ) ans=\frac{n!}{m!}\phi(m!) ans=m!n!ϕ(m!)
怎么求呢。
n ! m ! ϕ ( m ! ) \frac{n!}{m!}\phi(m!) m!n!ϕ(m!)

= n ! m ! m ! ∏ i = 1 k ( 1 − 1 p i ) =\frac{n!}{m!}m!\prod_{i=1}^{k}(1-\frac{1}{p_i}) =m!n!m!i=1k(1pi1)

= n ! ∏ i = 1 k p i − 1 p i =n!\prod_{i=1}^{k}\frac{p_i-1}{p_i} =n!i=1kpipi1

这个又怎么做呢?
n ! n! n!直接预处理即可。
f n = ∏ i = 1 k p − 1 p f_n=\prod_{i=1}^{k}\frac{p-1}{p} fn=i=1kpp1
后面的考虑我们已经求出了 f a f_a fa,那么 f a ∗ p r i m e = f a ∗ p r i m e − 1 p r i m e f_{a*prime}=f_a*\frac{prime-1}{prime} faprime=faprimeprime1,由于我们可以预处理逆元,因此可以 Θ ( 1 ) \Theta(1) Θ(1)转移。
因为 p i p_i pi的指数必须为 1 1 1,因此我们可以从小到大来做。

实测 n < r nn<r,不然对于没有逆元 n = k r , k ∈ N + n=kr,k∈N_+ n=kr,kN+的,直接做会有问题,详细处理方法可以见题解。

代码:

#include
#include
#include
#define LL long long
#define R register
using namespace std;
	int n,m,mod;
	int prime[1000010],fac[10000010],f[10000010],inv[10000010];
	bool bz[10000010];
void init(int ma)
{
	int t=0;
	bz[0]=bz[1]=true;
	for(R int i=2;i<=ma;i++)
	{
		if(!bz[i]) prime[++t]=i;
		for(R int j=1;j<=t&&i*prime[j]<=ma;j++)
		{
			bz[i*prime[j]]=true;
			if(!(i%prime[j])) break;
		}
	}
	fac[0]=1;
	for(R int i=1;i<=ma;i++)
		fac[i]=(LL)fac[i-1]*i%mod;
	inv[0]=inv[1]=1;
	for(R int i=2;i<=min(ma,mod-1);i++)
		inv[i]=((LL)mod-mod/i)*inv[mod%i]%mod;
	f[1]=1;
	for(R int i=2;i<=ma;i++)
	{
		f[i]=f[i-1];
		if(!bz[i]) f[i]=(LL)f[i]*inv[i]%mod*(i-1)%mod;
	}
}
int main()
{
	int T;
	scanf("%d %d",&T,&mod);
	init(10000000);
	while(T--)
	{
		scanf("%d %d",&n,&m);
		printf("%d\n",(LL)fac[n]*f[m]%mod);
	}
}

你可能感兴趣的:(#,神奇的数学问题,数论)