SDOI 2008沙拉公主的困惑

来源:互联网 发布:python mako 编辑:程序博客网 时间:2024/04/29 11:54

星期四, 23. 二月 2017 05:10下午

SDOI 2008沙拉公主的困惑
题目大意
求1-N!中与M!互质的数的个数;

思路

参考神犇の博客

N>M
N!M!
所以我们可以将N!分为N!M!段,那么这样的话,每段长度为M!
p与q互质
p+k仍然与q互质
那么 根据这个性质,就可以得到等式
sum=N!M!φ(M!)
  =N!M!M!(111p1)(111p2)(111p3)(111pk)
  =N!(111p1)(111p2)(111p3)(111pk)

先预处理出N!和φ(M!)可以做到蜜汁O(1)出解;

#include <cstdio>#include <algorithm>#include <cmath>#define max(a,b) a>b?a:busing namespace std;typedef long long LL;const int MAXN = 10000000+50;const int N = 10000+50;int fac[MAXN],sum[MAXN],inv[MAXN],num;int t,mod,A[N],B[N],maxn;int prime1[MAXN];bool prime[MAXN];void Read(int &);void init(int Maxn){    Maxn++;    sum[1]=1,fac[1]=1,inv[1]=1;    for(int i=2;i<Maxn;i++){        if(!prime[i])            prime1[++num]=i;        for(int j=1;j<=num && i*prime1[j]<Maxn;j++){               prime[i*prime1[j]]=1;            if(i%prime1[j]==0) break;        }    }    //线性筛函数    for(int i=2;i<=Maxn;i++)    {        sum[i]=((LL)sum[i-1]*i%mod)%mod; //预处理阶乘        if(i<mod)    inv[i]=(LL)(mod-mod/i)%mod*inv[mod%i]%mod;//预处理逆元        if(!prime[i])    fac[i]=(LL)fac[i-1]*(i-1)%mod*inv[i%mod]%mod;        else fac[i]=fac[i-1];    } //改成三个循环TLE3个点;}int main(){    Read(t),Read(mod);    for(int i=1;i<=t;i++)        Read(A[i]),Read(B[i]),maxn=max(maxn,A[i]);    init(maxn);    for(int i=1;i<=t;i++)        printf("%lld\n",(LL)fac[B[i]]*sum[A[i]]%mod);    return 0;}void Read(int &in){    static char ch;    for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) ;    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';}
0 0
原创粉丝点击