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

来源:互联网 发布:活性炭吸附甲醛 知乎 编辑:程序博客网 时间:2024/05/01 11:48

题意

求[1,n!]内有多少个数与m!互质
n,m<=10000000

分析

这么弱的题我居然都没想到。。。
首先肯定满足若x与m!互质,则x+m!和x-m!必然也与m!互质,那么答案就是ϕ(m!)n!/m!
剩下乱搞即可。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define N 10050005#define LL long longusing namespace std;int jc[N],tot,prime[N],s[N],MOD;bool not_prime[N];void get_prime(int n){    for (int i=2;i<=n;i++)    {        if (!not_prime[i]) prime[++tot]=i;        for (int j=1;j<=tot&&i*prime[j]<=n;j++)        {            not_prime[i*prime[j]]=1;            if (i%prime[j]==0) break;        }    }}int ksm(int x,int y){    int ans=1;    while (y)    {        if (y&1) ans=(LL)ans*x%MOD;        x=(LL)x*x%MOD;y>>=1;    }    return ans;}void prework(){    get_prime(10005000);    s[0]=1;    for (int i=1;i<=tot;i++)        s[i]=(LL)s[i-1]*ksm(prime[i],MOD-2)%MOD*(prime[i]-1)%MOD;    jc[0]=1;    for (int i=1;i<=10000000;i++) jc[i]=(LL)jc[i-1]*i%MOD;}int main(){    int T;    scanf("%d%d",&T,&MOD);    prework();    while (T--)    {        int n,m;        scanf("%d%d",&n,&m);        int w=upper_bound(prime+1,prime+tot+1,m)-prime-1;        printf("%d\n",(LL)s[w]*jc[n]%MOD);    }    return 0;}
0 0
原创粉丝点击