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

来源:互联网 发布:淘宝网络崩溃怎么解决 编辑:程序博客网 时间:2024/04/29 03:05

Portal

小于等于m!中与m!互质的数的个数就是phi(m!),求n!以内且n>=m中与m!互质的个数就是phi(m!)n!m!,因为若xm!互质,那么x+m!m!互质,x+2m!m!也互质……n!一定是m!的整数倍,所以就有phi(m!)n!m!个。
phi(m!)=m!p[i]1p[i]
p[i]为质因数。
那么答案就是p[i]1p[i]n!
分别预处理一下就行了。求逆元可以用费马小定理或者扩展欧几里得。

也不知道是不是自己写丑了。。扩欧比快速幂快了3s。。

费马小定理,用快速幂求逆元。(卡着时限过。。)

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <map>#define N 10000005#define INF 0x7fffffffusing namespace std;typedef long long ll;typedef pair<int,int> pa;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int T,mod,n,m;int p[664580],Not_Prime[N]={1,1},sum[N],Jc[N];int f[N];void Get_Prime(){    for(int i=2;i<N;i++)    {        if(!Not_Prime[i]) p[++p[0]]=i;        for(int j=1;j<=p[0]&&(ll)i*p[j]<N;j++)        {            Not_Prime[i*p[j]]=1;            if(!(i%p[j])) break;        }    }}int Qpow(int x,int y){    int rtn=1;    while(y) {        if(y&1) rtn=((ll)rtn*x)%mod;        x=((ll)x*x)%mod;y>>=1;    }    return rtn;}int main(){    T=read(),mod=read();    Get_Prime();f[1]=Jc[1]=1;    for(int i=2;i<N;i++) Jc[i]=((ll)Jc[i-1]*i)%mod;    for(int i=2;i<N;i++)     {        f[i]=f[i-1];        if(!Not_Prime[i]) f[i]=(ll)f[i]*Qpow(i,mod-2)%mod*(ll)(i-1)%mod;    }    while(T--)    {        n=read(),m=read();        printf("%d\n",(ll)Jc[n]*f[m]%mod);    }    return 0;}

扩欧求逆元

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <map>#define N 10000005#define INF 0x7fffffffusing namespace std;typedef long long ll;typedef pair<int,int> pa;int read(){    int x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int T,mod,n,m;int p[664580],Not_Prime[N]={1,1},sum[N],Jc[N];int f[N];void Get_Prime(){    for(int i=2;i<N;i++)    {        if(!Not_Prime[i]) p[++p[0]]=i;        for(int j=1;j<=p[0]&&(ll)i*p[j]<N;j++)        {            Not_Prime[i*p[j]]=1;            if(!(i%p[j])) break;        }    }}int exgcd(int a,int b,int &x,int &y){    int rtn=a;    if(b) {        rtn=exgcd(b,a%b,y,x);        y-=(a/b)*x;    }    else x=1,y=0;    return rtn;}int main(){    T=read(),mod=read();    Get_Prime();f[1]=Jc[1]=1;    for(int i=2;i<N;i++) Jc[i]=((ll)Jc[i-1]*i)%mod;    for(int i=2;i<N;i++)     {        f[i]=f[i-1];        if(!Not_Prime[i])         {            int x,y;            exgcd(i,mod,x,y);x%=mod;while(x<0) x+=mod;            f[i]=(ll)f[i]*x%mod*(ll)(i-1)%mod;        }    }    while(T--)    {        n=read(),m=read();        printf("%d\n",(ll)Jc[n]*f[m]%mod);    }    return 0;}
0 0
原创粉丝点击