题目:
题解:
基础:
(a,b)=1
那么
(a+b,b)=1
;因为n>m,
m!|n!
φ(m!)
为1~m!中与m!互质的个数,每个数加上m!的倍数依然与m!互质
那么答案就是
φ(m!)∗n!m!
画柿子咯
ans=φ(m!)∗n!m!=m!∏i=1pi−1pi∗n!m!=n!∏i=1pi−1pi
其中 m!=∏i=1pkii
如果将m!分解质因数的话,所有小于等于m的质因子次数都至少为1,而需要求的这个式子与质因子次数并没有关系,那么直接对所有小于等于m的质因子做就可以了
因为从1-m的质因数的乘积要求很多次,预处理是非常好的
代码:
#include <cstdio>
#include <iostream>
#define TT 10005
#define LL long long
using namespace std;
const int M=10000000;
int mod,n[TT],m[TT],maxxm,maxxn,p[M+5],ll=0,wh[M+5];
LL mul[M+5],phi[M+5];
bool ss[M+5];
LL ksm(LL a,LL k)
{
LL ans=1;
for (;k;k>>=1,a=a*a%mod)
if (k&1) ans=ans*a%mod;
return ans;
}
void pre()
{
int i;
for (i=2;i<=maxxm;i++)
{
if (!ss[i]) p[++ll]=i;
wh[i]=ll;
for (int j=1;j<=ll && p[j]*i<=maxxm;j++)
{
ss[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
mul[1]=1;for (int i=2;i<=maxxn;i++) mul[i]=mul[i-1]*i%mod;
phi[0]=1;
for (i=1;i<=ll;i++)
{
LL ans=(LL)(p[i]-1)*ksm(p[i]%mod,mod-2)%mod;
phi[i]=phi[i-1]*ans%mod;
}
}
int main()
{
int T,i;
scanf("%d%d",&T,&mod);
for (i=1;i<=T;i++)
{
scanf("%d%d",&n[i],&m[i]);
maxxn=max(maxxn,n[i]);
maxxm=max(maxxm,m[i]);
}
pre();
for (i=1;i<=T;i++)
printf("%d\n",(LL)phi[wh[m[i]]]*mul[n[i]]%mod);
}