bzoj2186: [Sdoi2008]沙拉公主的困惑

来源:互联网 发布:济南优创数据待遇如何 编辑:程序博客网 时间:2024/04/29 08:22

传送门
题目要求求出phi(m!)*(n!/m!)
注意到phi(m!)=m!*(p-1)/p(p是m!的质因子),模数固定。
所以答案就是n!*(p-1)/p(p是m!的质因子)
n!可以在线性时间内求出,(p-1)/p(p是m!的质因子)也可以用线性筛求出。
本题略卡时限。
注意:1.10000000以内质数仅有不到500000个,我们可以用递归求逆元加速运算。
2.采用某些松松松的技巧可以避免超时。

#include<iostream>#include<cstdio>#define ll long long#define M 10000000using namespace std;int f[M+5];ll n,mo,x,y,p[M+5],q[M+5];int u,v;int read(){    int k=0;    char ch=getchar();    for (;ch<'0'||ch>'9';ch=getchar());    for (;ch>='0'&&ch<='9';ch=getchar()) k=k*10+ch-48;    return k;}ll inv(int x){    return (p[x])?p[x]:p[x]=(mo-mo/x)*inv(mo%x)%mo;}int main(){    n=read();    mo=read();    f[1]=p[1]=q[1]=p[0]=1;    for (int i=2;i*i<=M;++i)        if (!f[i]) for (int j=i*i;j<=M;j+=i) f[j]=1;    for (ll i=2;i<=M;++i)        q[i]=(f[i])?q[i-1]:q[i-1]*(i-1)%mo*inv(i%mo)%mo;    p[1]=1;    for (ll i=2;i<=M;++i) p[i]=p[i-1]*i%mo;    while (n--){        x=read();        y=read();        printf("%lld\n",p[x]*q[y]%mo);    }    return 0;}
2 1
原创粉丝点击