题目大意:求1~n!中与m!互质的数的个数%R(一个质数),多组询问
题解:根据phi的定义可以得到phi(m!)表示[1,m!)中与m!互质的数的个数
有一个性质: gcd(i,j)=gcd(i+j,j)
那么gcd(i,m!)=1,gcd(i+m!,m!)=1,所以每个m!以内和m!互质的数都可以通过这个方法拓展
对于每个i,算上自己一共可以拓展n!/m!次,那么答案就是phi(m!)*n!/m!
然后可以把phi拆开……
phi(m!)=m!∗∏((pi−1)/pi)
pi
为m!的所有质因子,也即m内所有质数
因为多组询问所以预处理……
我的收获:欧拉函数……
#include <bits/stdc++.h>
using namespace std;
#define INF 1000000000
#define N 10000000
#define ll long long
int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
int T,R,n,m,cnt;
int fac[N+5],ine[N+5],pri[N],ans[N+5];
bool mark[N+5];
void pre()
{
fac[1]=1;for(int i=2;i<=N;i++)fac[i]=(ll)fac[i-1]*i%R;
ine[1]=1;
for(int i=2;i<=N;i++)
{
if(!mark[i]) pri[++cnt]=i;
for(int j=1;pri[j]*i<=N&&j<=cnt;j++)
{
mark[pri[j]*i]=1;
if(i%pri[j]==0)break;
}
}
for(int i=2;i<=N&&i<R;i++)
ine[i]=(R-(ll)R/i*ine[R%i]%R);
ans[1]=1;
for(int i=2;i<=N;i++)
{
ans[i]=ans[i-1];
if(!mark[i]) ans[i]=(ll)ans[i]*(i-1)%R*ine[i%R]%R;
}
}
int main()
{
T=read();R=read();
pre();
while(T--)
{
n=read();m=read();
printf("%lld\n",(ll)fac[n]*ans[m]%R);
}
return 0;
}